00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
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
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
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
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 GWEN_Io_Layer_AddFlags(io, GWEN_IO_LAYER_BUFFERED_FLAGS_DOSMODE);
00367
00368
00369 ioBase=io;
00370 io=GWEN_Io_LayerHttp_new(ioBase);
00371 if (io==NULL) {
00372 GWEN_InetAddr_free(addr);
00373 GWEN_Io_Layer_free(ioBase);
00374 return GWEN_ERROR_GENERIC;
00375 }
00376
00377
00378 db=GWEN_Io_LayerHttp_GetDbCommandOut(io);
00379 if (sess->httpVMajor) {
00380 char numbuf[32];
00381
00382 snprintf(numbuf, sizeof(numbuf)-1, "HTTP/%d.%d",
00383 sess->httpVMajor, sess->httpVMinor);
00384 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", numbuf);
00385 }
00386 else
00387 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", "HTTP/1.0");
00388
00389 if (1) {
00390 GWEN_BUFFER *pbuf;
00391
00392 pbuf=GWEN_Buffer_new(0, 256, 0, 1);
00393 rv=GWEN_Url_toCommandString(sess->url, pbuf);
00394 if (rv) {
00395 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00396 GWEN_Buffer_free(pbuf);
00397 GWEN_InetAddr_free(addr);
00398 GWEN_Io_Layer_free(ioBase);
00399 return rv;
00400 }
00401 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "url",
00402 GWEN_Buffer_GetStart(pbuf));
00403 GWEN_Buffer_free(pbuf);
00404 }
00405
00406
00407 db=GWEN_Io_LayerHttp_GetDbHeaderOut(io);
00408 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00409 "Host", GWEN_Url_GetServer(sess->url));
00410 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00411 "Pragma", "no-cache");
00412 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00413 "Cache-control", "no cache");
00414 if (sess->httpContentType)
00415 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00416 "Content-type", sess->httpContentType);
00417
00418 if (sess->httpUserAgent)
00419 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00420 "User-Agent", sess->httpUserAgent);
00421 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "close");
00422 GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-length", 0);
00423
00424
00425 rv=GWEN_Io_Manager_RegisterLayer(io);
00426 if (rv<0) {
00427 DBG_INFO(GWEN_LOGDOMAIN, "Could not register io layer (%d)", rv);
00428 GWEN_InetAddr_free(addr);
00429 GWEN_Io_Layer_free(io);
00430 return 0;
00431 }
00432
00433 sess->ioLayer=io;
00434 GWEN_InetAddr_free(addr);
00435 return 0;
00436 }
00437
00438
00439
00440 int GWEN_HttpSession_Fini(GWEN_HTTP_SESSION *sess) {
00441 assert(sess);
00442 assert(sess->usage);
00443
00444 GWEN_Io_Layer_free(sess->ioLayer);
00445 sess->ioLayer=0;
00446 return 0;
00447 }
00448
00449
00450
00451 int GWEN_HttpSession_SendPacket(GWEN_HTTP_SESSION *sess,
00452 const char *httpCommand,
00453 const uint8_t *buf, uint32_t blen,
00454 int timeout) {
00455 int rv;
00456
00457 assert(sess);
00458 assert(sess->usage);
00459
00460
00461 GWEN_Gui_ProgressLog(sess->guiid,
00462 GWEN_LoggerLevel_Notice,
00463 I18N("Connecting to server..."));
00464 rv=GWEN_Io_Layer_ConnectRecursively(sess->ioLayer, NULL, 0,
00465 sess->guiid, 30000);
00466 if (rv==GWEN_ERROR_SSL) {
00467 GWEN_IO_LAYER *ioTls;
00468
00469
00470 DBG_NOTICE(GWEN_LOGDOMAIN,
00471 "SSL-Error connecting (%d), retrying", rv);
00472 GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00473 GWEN_IO_REQUEST_FLAGS_FORCE,
00474 sess->guiid, 2000);
00475 ioTls=GWEN_Io_Layer_FindBaseLayerByType(sess->ioLayer,
00476 GWEN_IO_LAYER_TLS_TYPE);
00477 assert(ioTls);
00478
00479 if (sess->flags & GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3) {
00480 DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (non-SSLv3)");
00481 GWEN_Gui_ProgressLog(sess->guiid,
00482 GWEN_LoggerLevel_Info,
00483 I18N("Retrying to connect (non-SSLv3)"));
00484 GWEN_Io_Layer_SubFlags(ioTls, GWEN_IO_LAYER_TLS_FLAGS_FORCE_SSL_V3);
00485 rv=GWEN_Io_Layer_ConnectRecursively(sess->ioLayer, NULL, 0,
00486 sess->guiid, 30000);
00487 if (rv==0) {
00488 GWEN_HttpSession_SubFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00489 }
00490 }
00491 else {
00492 DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (SSLv3)");
00493 GWEN_Gui_ProgressLog(sess->guiid,
00494 GWEN_LoggerLevel_Info,
00495 I18N("Retrying to connect (SSLv3)"));
00496 GWEN_Io_Layer_AddFlags(ioTls, GWEN_IO_LAYER_TLS_FLAGS_FORCE_SSL_V3);
00497 rv=GWEN_Io_Layer_ConnectRecursively(sess->ioLayer, NULL, 0,
00498 sess->guiid, 30000);
00499 if (rv==0) {
00500 GWEN_HttpSession_AddFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00501 }
00502 }
00503 }
00504
00505 if (rv<0) {
00506 DBG_INFO(GWEN_LOGDOMAIN, "Could not connect to server (%d)", rv);
00507 GWEN_Gui_ProgressLog(sess->guiid,
00508 GWEN_LoggerLevel_Error,
00509 I18N("Could not connect to server"));
00510 GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00511 GWEN_IO_REQUEST_FLAGS_FORCE,
00512 sess->guiid, 2000);
00513 return rv;
00514 }
00515 else {
00516 GWEN_DB_NODE *db;
00517
00518 GWEN_Gui_ProgressLog(sess->guiid,
00519 GWEN_LoggerLevel_Info,
00520 I18N("Connected."));
00521
00522
00523 db=GWEN_Io_LayerHttp_GetDbCommandOut(sess->ioLayer);
00524 GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00525 "command",
00526 httpCommand);
00527
00528
00529 db=GWEN_Io_LayerHttp_GetDbHeaderOut(sess->ioLayer);
00530 GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00531 "Content-length", blen);
00532
00533 GWEN_Gui_ProgressLog(sess->guiid,
00534 GWEN_LoggerLevel_Info,
00535 I18N("Sending message..."));
00536 rv=GWEN_Io_Layer_WriteBytes(sess->ioLayer,
00537 buf, blen,
00538 GWEN_IO_REQUEST_FLAGS_PACKETBEGIN |
00539 GWEN_IO_REQUEST_FLAGS_PACKETEND |
00540 GWEN_IO_REQUEST_FLAGS_FLUSH,
00541 sess->guiid, timeout);
00542 if (rv<0) {
00543 DBG_INFO(GWEN_LOGDOMAIN, "Could not send message (%d)", rv);
00544 GWEN_Gui_ProgressLog(sess->guiid,
00545 GWEN_LoggerLevel_Error,
00546 I18N("Could not send message"));
00547 GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00548 GWEN_IO_REQUEST_FLAGS_FORCE,
00549 sess->guiid, 2000);
00550 return rv;
00551 }
00552
00553 DBG_INFO(GWEN_LOGDOMAIN, "Message sent.");
00554 GWEN_Gui_ProgressLog(sess->guiid,
00555 GWEN_LoggerLevel_Info,
00556 I18N("Message sent."));
00557 return 0;
00558 }
00559 }
00560
00561
00562
00563 int GWEN_HttpSession__RecvPacket(GWEN_HTTP_SESSION *sess,
00564 GWEN_BUFFER *buf, GWEN_UNUSED int timeout) {
00565 int rv;
00566 GWEN_DB_NODE *db;
00567 int code;
00568
00569 assert(sess);
00570 assert(sess->usage);
00571
00572
00573 rv=GWEN_Io_Layer_ReadPacketToBuffer(sess->ioLayer, buf, 0,
00574 sess->guiid, 30000);
00575 if (rv<0) {
00576 if (GWEN_Buffer_GetUsedBytes(buf)) {
00577
00578 if (rv==GWEN_ERROR_EOF || (rv==GWEN_ERROR_IO)) {
00579 DBG_INFO(GWEN_LOGDOMAIN,
00580 "We received an error, but we still got data, "
00581 "so we ignore the error here");
00582 }
00583 else {
00584 DBG_INFO(GWEN_LOGDOMAIN, "No message received (%d)", rv);
00585 GWEN_Gui_ProgressLog(sess->guiid,
00586 GWEN_LoggerLevel_Error,
00587 I18N("No message received"));
00588 return rv;
00589 }
00590 }
00591 else {
00592 DBG_INFO(GWEN_LOGDOMAIN, "No message received (%d)", rv);
00593 GWEN_Gui_ProgressLog(sess->guiid,
00594 GWEN_LoggerLevel_Error,
00595 I18N("No message received"));
00596 return rv;
00597 }
00598 }
00599
00600
00601 db=GWEN_Io_LayerHttp_GetDbStatusIn(sess->ioLayer);
00602 code=GWEN_DB_GetIntValue(db, "code", 0, 0);
00603 if (code) {
00604 GWEN_BUFFER *lbuf;
00605 char sbuf[32];
00606 const char *text;
00607
00608 lbuf=GWEN_Buffer_new(0, 64, 0, 1);
00609 GWEN_Buffer_AppendString(lbuf, "HTTP-Status: ");
00610 snprintf(sbuf, sizeof(sbuf)-1, "%d", code);
00611 sbuf[sizeof(sbuf)-1]=0;
00612 GWEN_Buffer_AppendString(lbuf, sbuf);
00613 text=GWEN_DB_GetCharValue(db, "text", 0, NULL);
00614 if (text) {
00615 GWEN_Buffer_AppendString(lbuf, " (");
00616 GWEN_Buffer_AppendString(lbuf, text);
00617 GWEN_Buffer_AppendString(lbuf, ")");
00618 }
00619 DBG_DEBUG(GWEN_LOGDOMAIN, "Status: %d (%s)",
00620 code, text);
00621 if (code<200 || code>299) {
00622
00623 if (code!=100) {
00624 GWEN_DB_NODE *dbHeaderIn;
00625
00626 dbHeaderIn=GWEN_Io_LayerHttp_GetDbHeaderIn(sess->ioLayer);
00627 DBG_ERROR(GWEN_LOGDOMAIN,
00628 "Got an error response (%d: %s)",
00629 code, text);
00630 GWEN_Gui_ProgressLog(sess->guiid,
00631 GWEN_LoggerLevel_Error,
00632 GWEN_Buffer_GetStart(lbuf));
00633 GWEN_Buffer_Reset(lbuf);
00634
00635 if (code==301 || code==303 || code==305 || code==307) {
00636
00637 if (dbHeaderIn) {
00638 const char *s;
00639
00640 s=GWEN_DB_GetCharValue(dbHeaderIn, "Location", 0, 0);
00641 if (s) {
00642 switch(code) {
00643 case 301:
00644 case 303:
00645 GWEN_Buffer_AppendString(lbuf,
00646 I18N("HTTP: Moved permanently"));
00647 break;
00648 case 305:
00649 GWEN_Buffer_AppendString(lbuf,
00650 I18N("HTTP: Use proxy"));
00651 break;
00652 case 307:
00653 GWEN_Buffer_AppendString(lbuf,
00654 I18N("HTTP: Moved temporarily"));
00655 break;
00656 default:
00657 GWEN_Buffer_AppendString(lbuf,
00658 I18N("HTTP: Moved"));
00659 }
00660 GWEN_Buffer_AppendString(lbuf, " (");
00661 GWEN_Buffer_AppendString(lbuf, s);
00662 GWEN_Buffer_AppendString(lbuf, ")");
00663
00664 GWEN_Gui_ProgressLog(sess->guiid,
00665 GWEN_LoggerLevel_Warning,
00666 GWEN_Buffer_GetStart(lbuf));
00667 }
00668 }
00669 }
00670 }
00671 else {
00672 GWEN_Gui_ProgressLog(sess->guiid,
00673 GWEN_LoggerLevel_Notice,
00674 GWEN_Buffer_GetStart(lbuf));
00675 }
00676 }
00677 else {
00678 GWEN_Gui_ProgressLog(sess->guiid,
00679 GWEN_LoggerLevel_Info,
00680 GWEN_Buffer_GetStart(lbuf));
00681 }
00682 GWEN_Buffer_free(lbuf);
00683 }
00684 else {
00685 DBG_ERROR(GWEN_LOGDOMAIN, "No HTTP status code received");
00686 GWEN_Gui_ProgressLog(sess->guiid,
00687 GWEN_LoggerLevel_Error,
00688 I18N("No HTTP status code received"));
00689 code=GWEN_ERROR_BAD_DATA;
00690 }
00691
00692 return code;
00693 }
00694
00695
00696
00697 int GWEN_HttpSession_RecvPacket(GWEN_HTTP_SESSION *sess,
00698 GWEN_BUFFER *buf, int timeout) {
00699 int rv;
00700 uint32_t pos;
00701
00702
00703 pos=GWEN_Buffer_GetPos(buf);
00704 for (;;) {
00705 GWEN_Gui_ProgressLog(sess->guiid,
00706 GWEN_LoggerLevel_Info,
00707 I18N("Waiting for response..."));
00708 rv=GWEN_HttpSession__RecvPacket(sess, buf, timeout);
00709 if (rv<0 || rv<200 || rv>299) {
00710 DBG_INFO(GWEN_LOGDOMAIN,
00711 "Error receiving packet (%d)", rv);
00712 GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00713 GWEN_IO_REQUEST_FLAGS_FORCE,
00714 sess->guiid, 2000);
00715 return rv;
00716 }
00717 if (rv!=100)
00718 break;
00719 GWEN_Gui_ProgressLog(sess->guiid,
00720 GWEN_LoggerLevel_Info,
00721 I18N("Received continuation response."));
00722 GWEN_Buffer_Crop(buf, 0, pos);
00723 }
00724
00725 GWEN_Gui_ProgressLog(sess->guiid,
00726 GWEN_LoggerLevel_Info,
00727 I18N("Response received."));
00728
00729
00730 GWEN_Gui_ProgressLog(sess->guiid,
00731 GWEN_LoggerLevel_Info,
00732 I18N("Disconnecting from server..."));
00733 GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00734 GWEN_IO_REQUEST_FLAGS_FORCE,
00735 sess->guiid, 2000);
00736 GWEN_Gui_ProgressLog(sess->guiid,
00737 GWEN_LoggerLevel_Info,
00738 I18N("Disconnected."));
00739
00740 return 0;
00741 }
00742
00743
00744
00745
00746
00747
00748