initial load of upstream version 1.06.32
[xmlrpc-c] / lib / abyss / src / session.c
1 #include <assert.h>
2 #include <sys/types.h>
3 #include <string.h>
4 #include <stdio.h>
5
6 #include "xmlrpc-c/util_int.h"
7 #include "xmlrpc-c/string_int.h"
8 #include "xmlrpc-c/abyss.h"
9 #include "server.h"
10 #include "http.h"
11 #include "conn.h"
12
13 #include "session.h"
14
15
16
17 abyss_bool
18 SessionRefillBuffer(TSession * const sessionP) {
19 /*----------------------------------------------------------------------------
20    Get the next chunk of HTTP request body from the connection into
21    the buffer.
22
23    I.e. read data from the socket.
24 -----------------------------------------------------------------------------*/
25     struct _TServer * const srvP = sessionP->conn->server->srvP;
26     abyss_bool failed;
27
28     failed = FALSE;  /* initial value */
29             
30     /* Reset our read buffer & flush data from previous reads. */
31     ConnReadInit(sessionP->conn);
32
33     if (sessionP->continueRequired)
34         failed = !HTTPWriteContinue(sessionP);
35
36     if (!failed) {
37         sessionP->continueRequired = FALSE;
38
39         /* Read more network data into our buffer.  If we encounter a
40            timeout, exit immediately.  We're very forgiving about the
41            timeout here.  We allow a full timeout per network read, which
42            would allow somebody to keep a connection alive nearly
43            indefinitely.  But it's hard to do anything intelligent here
44            without very complicated code.
45         */
46         failed = !ConnRead(sessionP->conn, srvP->timeout);      
47     }
48     return !failed;
49 }
50
51
52
53 size_t
54 SessionReadDataAvail(TSession * const sessionP) {
55
56     return sessionP->conn->buffersize - sessionP->conn->bufferpos;
57
58 }
59
60
61
62 void
63 SessionGetReadData(TSession *    const sessionP, 
64                    size_t        const max, 
65                    const char ** const outStartP, 
66                    size_t *      const outLenP) {
67 /*----------------------------------------------------------------------------
68    Extract some HTTP request body which the server has read and
69    buffered for the session.  Don't get or wait for any data that has
70    not yet arrived.  Do not return more than 'max'.
71
72    We return a pointer to the first byte as *outStartP, and the length in
73    bytes as *outLenP.  The memory pointed to belongs to the session.
74 -----------------------------------------------------------------------------*/
75     uint32_t const bufferPos = sessionP->conn->bufferpos;
76
77     *outStartP = &sessionP->conn->buffer[bufferPos];
78
79     assert(bufferPos <= sessionP->conn->buffersize);
80
81     *outLenP = MIN(max, sessionP->conn->buffersize - bufferPos);
82
83     /* move pointer past the bytes we are returning */
84     sessionP->conn->bufferpos += *outLenP;
85
86     assert(sessionP->conn->bufferpos <= sessionP->conn->buffersize);
87 }
88
89
90
91 void
92 SessionGetRequestInfo(TSession *            const sessionP,
93                       const TRequestInfo ** const requestInfoPP) {
94     
95     *requestInfoPP = &sessionP->request_info;
96 }
97
98
99
100 abyss_bool
101 SessionLog(TSession * const sessionP) {
102
103     abyss_bool retval;
104
105     if (!sessionP->validRequest)
106         retval = FALSE;
107     else {
108         const char * const user = sessionP->request_info.user;
109
110         const char * logline;
111         char date[30];
112
113         DateToLogString(&sessionP->date, date);
114
115         xmlrpc_asprintf(&logline, "%d.%d.%d.%d - %s - [%s] \"%s\" %d %d",
116                         IPB1(sessionP->conn->peerip),
117                         IPB2(sessionP->conn->peerip),
118                         IPB3(sessionP->conn->peerip),
119                         IPB4(sessionP->conn->peerip),
120                         user ? user : "",
121                         date, 
122                         sessionP->request_info.requestline,
123                         sessionP->status,
124                         sessionP->conn->outbytes
125             );
126         if (logline) {
127             LogWrite(sessionP->conn->server, logline);
128
129             xmlrpc_strfree(logline);
130         }
131         retval = TRUE;
132     }
133     return retval;
134 }
135
136
137