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);

Reply via email to