1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3 
4   This file is part of SOPE.
5 
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10 
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15 
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21 
22 #include "common.h"
23 #include "NGBufferedDescriptor.h"
24 
NGScanResponseLine(NGBufferedDescriptor * _in,unsigned char * _version,int * _status,unsigned char * _text)25 unsigned char NGScanResponseLine(NGBufferedDescriptor *_in,
26                                  unsigned char *_version, int *_status,
27                                  unsigned char *_text)
28 {
29   if (_in == NULL) return 0;
30 
31   if (_version) *_version = '\0';
32   if (_text)    *_text    = '\0';
33   if (_status)  *_status  = '\0';
34 
35   {
36     int c;
37     int i;
38 
39     /* scan HTTP Version */
40     {
41       c = NGBufferedDescriptor_readChar(_in);
42       i = 0;
43       while ((c > 0) && !apr_isspace(c) && (i < 16)) {
44         if (_version) _version[i] = c;
45         i++;
46         c = NGBufferedDescriptor_readChar(_in);
47       }
48       if (_version) _version[i] = '\0';
49       if (c < 1) return 0; // read error
50     }
51 
52     /* skip spaces */
53     while ((c > 0) && apr_isspace(c))
54       c = NGBufferedDescriptor_readChar(_in);
55     if (c < 1) return 0; // read error
56 
57     /* scan code */
58     {
59       char buf[10];
60       i = 0;
61       while ((c > 0) && !apr_isspace(c) && (c != '\r') && (c != '\n') &&
62              (i < 6)) {
63         buf[i] = c;
64         i++;
65         c = NGBufferedDescriptor_readChar(_in);
66       }
67       buf[i] = '\0';
68       if (_status) *_status = atoi(buf);
69     }
70 
71     /* skip spaces */
72     while ((c > 0) && apr_isspace(c))
73       c = NGBufferedDescriptor_readChar(_in);
74     if (c < 1) return 0; // read error
75 
76     /* check for EOL */
77     if (c == '\n') return 1; // response without reason
78     if (c == '\r') { // response without reason
79       c = NGBufferedDescriptor_readChar(_in); // c=='\n'
80       return 1;
81     }
82 
83     /* scan reason */
84     {
85       i = 0;
86       while ((c > 0) && !apr_isspace(c) && (c != '\r') && (c != '\n') &&
87              (i < 6)) {
88         if (_text) _text[i] = c;
89         i++;
90         c = NGBufferedDescriptor_readChar(_in);
91       }
92       if (_text) _text[i] = '\0';
93       if (c < 1) return 0; // read error
94     }
95 
96     /* scan until line end */
97     while ((c > 0) && (c != '\n'))
98       c = NGBufferedDescriptor_readChar(_in);
99 
100     if (c < 1) return 0; // read error
101   }
102   return 1;
103 }
104 
NGScanHeaders(apr_pool_t * _pool,NGBufferedDescriptor * _in)105 apr_table_t *NGScanHeaders(apr_pool_t *_pool, NGBufferedDescriptor *_in) {
106   apr_table_t *headers = NULL;
107 
108   if (_in == NULL) return NULL;
109 
110   headers = apr_table_make(_pool, 64);
111   if (headers) {
112     char name[256];
113     char value[8000];
114     int c;
115 
116     while (1) {
117       int i, j;
118 
119       c = NGBufferedDescriptor_readChar(_in);
120       if (c <= 0) // error
121         break;
122 
123       // test for end of HTTP header
124       {
125         if (c == '\n') // end line '\n'
126           break;
127         if (c == '\r') { // end line '\r\n'
128           c = NGBufferedDescriptor_readChar(_in);
129           // c should be '\n'
130           break;
131         }
132       }
133 
134       // scan name
135       {
136         i = 0;
137         while ((c > 0) && (c != ':') && (i < 255)) {
138           name[i] = c;
139           i++;
140           c = NGBufferedDescriptor_readChar(_in);
141         }
142         name[i] = '\0';
143         if (i < 1) break; // empty header name ?!
144       }
145       if (c != ':') break; // missing separator ?
146 
147       // skip spaces following separator
148       c = NGBufferedDescriptor_readChar(_in);
149       while ((c > 0) && (apr_isspace(c)))
150         c = NGBufferedDescriptor_readChar(_in);
151 
152       // scan value
153       {
154         j = 0;
155         while ((c > 0) && (c != '\r') && (j < 7999)) {
156           value[j] = c;
157           j++;
158           c = NGBufferedDescriptor_readChar(_in);
159         }
160         value[j] = '\0';
161         if (j < 1) break; // empty header value ?!
162       }
163 
164       if (c == '\n') // '\n' header end
165         ;
166       else if (c == '\r') { // '\r\n' header end
167         c = NGBufferedDescriptor_readChar(_in);
168         if (c != '\n') break;
169       }
170       else // no valid header end
171         break;
172 
173       // store value
174       apr_table_add(headers, name, value);
175     }
176   }
177   return headers;
178 }
179