Stipe Tolj wrote: > Oded Arbel wrote:
>>Speaking of sendsms' HTTP interface - I've noticed that sendsms doesn't >>honor the 'Connection: close' header and always use keep-alive. can that be >>fixed, please ? > I had a look in gwlib/http.c:899 where the following is inside > handle_transaction(): > [...] > h = http_header_find_first(trans->response->headers, > "Connection"); > if (h != NULL && octstr_compare(h, octstr_imm("close")) == 0) > trans->persistent = 0; > octstr_destroy(h); > #if 1 /* Reuse enabled again, let's see if anyone complains... */ > if (trans->persistent) > conn_pool_put(trans->conn, trans->host, trans->port); > else > #endif > conn_destroy(trans->conn); > [...] > this seems to honor the "Connection: close" statement, didn't it?! Yes, the client side is ok. The server side then... I made a patch that adds a persistency value into the client object that the server side uses to store the information about the client. This value is added with a function with these rules: HTTP version 1.0 => non-persistent connection HTTP version 1.0 + Connection: keep-alive => persistent connection HTTP version 1.1 => persistent connection HTTP version 1.1 + Connection: close => non-persistent connection The outgoing headers are checked too, so if the server sends out "Connection: close", the connection is changed to non-persistent. > Can you describe how we can reproduce the effect you see, so that we > may analyze ourselfs?! My problem with the smsc_http was introduced with a nonkannel HTTP 1.1 client, that kept posting sms:es in through different connections and Kannel then kept these connections open so long that idle connections built up to a point where the sockets run out. Now the code dealing with this client in the smsc_http.c adds this "Connection: close" header and the HTTP server then knows to hangup the connection after replying about the sent sms. So, if no-one opposes, I'll add this patch into the CVS. -- Tuomas Luttinen Application Developer -- Reach U **************
Index: gwlib/http.c =================================================================== RCS file: /home/cvs/gateway/gwlib/http.c,v retrieving revision 1.156 diff -c -r1.156 http.c *** gwlib/http.c 2001/12/21 01:55:50 1.156 --- gwlib/http.c 2002/01/15 11:27:15 *************** *** 989,995 **** { Octstr *prefix, *prefix_https; long prefix_len; ! int host_len, colon, slash, at, auth_sep; prefix = octstr_imm("http://"); prefix_https = octstr_imm("https://"); --- 989,995 ---- { Octstr *prefix, *prefix_https; long prefix_len; ! int host_len, colon, slash, at, auth_sep = -1; prefix = octstr_imm("http://"); prefix_https = octstr_imm("https://"); *************** *** 1362,1367 **** --- 1362,1368 ---- int method; /* HTTP_METHOD_ value */ Octstr *url; int use_version_1_0; + int persistent_conn; HTTPEntity *request; }; *************** *** 1385,1390 **** --- 1386,1392 ---- p->state = reading_request_line; p->url = NULL; p->use_version_1_0 = 0; + p->persistent_conn = 1; p->request = NULL; return p; } *************** *** 1420,1425 **** --- 1422,1452 ---- /* + * Checks whether the client connection is meant to be persistent or not. + * Returns 1 for true, 0 for false. + */ + + static int client_is_persistent(List *headers, int use_version_1_0) + { + Octstr *h = http_header_find_first(headers, "Connection"); + + if (h == NULL) { + return !use_version_1_0; + } else { + if (use_version_1_0) { + if (octstr_compare(h, octstr_imm("keep-alive")) == 0) + return 1; + else + return 0; + } else if (octstr_compare(h, octstr_imm("close")) == 0) + return 0; + } + + return 1; + } + + + /* * Port specific lists of clients with requests. */ *************** *** 1644,1650 **** if (conn_outbuf_len(conn) > 0) return; /* Reply has been sent completely */ ! if (client->use_version_1_0) { client_destroy(client); return; } --- 1671,1677 ---- if (conn_outbuf_len(conn) > 0) return; /* Reply has been sent completely */ ! if (!client->persistent_conn) { client_destroy(client); return; } *************** *** 1903,1908 **** --- 1930,1938 ---- octstr_destroy(*body); *body = NULL; } + + client->persistent_conn = client_is_persistent(client->request->headers, + client->use_version_1_0); client->url = NULL; client->request->headers = NULL; *************** *** 1919,1931 **** { Octstr *response; long i; ! int ret; if (client->use_version_1_0) response = octstr_format("HTTP/1.0 %d Foo\r\n", status); else response = octstr_format("HTTP/1.1 %d Foo\r\n", status); octstr_format_append(response, "Content-Length: %ld\r\n", octstr_len(body)); for (i = 0; i < list_len(headers); ++i) --- 1949,1966 ---- { Octstr *response; long i; ! int ret, p; if (client->use_version_1_0) response = octstr_format("HTTP/1.0 %d Foo\r\n", status); else response = octstr_format("HTTP/1.1 %d Foo\r\n", status); + if (!client->use_version_1_0 && + (p = client_is_persistent(headers, client->use_version_1_0)) != + client->persistent_conn) + client->persistent_conn = p; + octstr_format_append(response, "Content-Length: %ld\r\n", octstr_len(body)); for (i = 0; i < list_len(headers); ++i) *************** *** 1939,1945 **** octstr_destroy(response); if (ret == 0) { /* Sent already */ ! if (client->use_version_1_0) client_destroy(client); else { client_reset(client); --- 1974,1980 ---- octstr_destroy(response); if (ret == 0) { /* Sent already */ ! if (!client->persistent_conn) client_destroy(client); else { client_reset(client);