comparison http.c @ 870:f641c96e431b

Some simple code to handle HTTP requests/responses.
author bertrand
date Fri, 25 May 2001 13:58:32 +0000
parents
children ede5785faa53
comparison
equal deleted inserted replaced
869:e350849ff400 870:f641c96e431b
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "http.h"
6
7 HTTP_header_t *
8 http_new_header() {
9 HTTP_header_t *http_hdr;
10
11 http_hdr = (HTTP_header_t*)malloc(sizeof(HTTP_header_t));
12 if( http_hdr==NULL ) return NULL;
13 memset( http_hdr, 0, sizeof(HTTP_header_t) );
14
15 return http_hdr;
16 }
17
18 void
19 http_free( HTTP_header_t *http_hdr ) {
20 int i;
21 if( http_hdr==NULL ) return;
22 if( http_hdr->protocol!=NULL ) free( http_hdr->protocol );
23 if( http_hdr->method!=NULL ) free( http_hdr->method );
24 if( http_hdr->uri!=NULL ) free( http_hdr->uri );
25 if( http_hdr->reason_phrase!=NULL ) free( http_hdr->reason_phrase );
26 if( http_hdr->body!=NULL ) free( http_hdr->body );
27 if( http_hdr->field_search!=NULL ) free( http_hdr->field_search );
28 for( i=0 ; i<http_hdr->field_nb ; i++ )
29 if( http_hdr->fields[i]!=NULL ) free( http_hdr->fields[i] );
30 free( http_hdr );
31 }
32
33 HTTP_header_t *
34 http_new_response( char *response, int length ) {
35 HTTP_header_t *http_hdr;
36 char *hdr_ptr, *ptr;
37 char *field=NULL;
38 int pos_hdr_sep, len;
39 if( response==NULL ) return NULL;
40
41 http_hdr = http_new_header();
42 if( http_hdr==NULL ) return NULL;
43
44 // Get the protocol
45 hdr_ptr = strstr( response, " " );
46 if( hdr_ptr==NULL ) {
47 printf("Malformed answer\n");
48 return NULL;
49 }
50 len = hdr_ptr-response;
51 http_hdr->protocol = (char*)malloc(len+1);
52 if( http_hdr->protocol==NULL ) {
53 printf("Memory allocation failed\n");
54 return NULL;
55 }
56 strncpy( http_hdr->protocol, response, len );
57 http_hdr->protocol[len+1]='\0';
58 if( !strncasecmp( http_hdr->protocol, "HTTP", 4) ) {
59 if( sscanf( http_hdr->protocol+5,"1.%d", &(http_hdr->http_minor_version) )!=1 ) {
60 printf("Malformed answer\n");
61 return NULL;
62 }
63 }
64
65 // Get the status code
66 if( sscanf( ++hdr_ptr, "%d", &(http_hdr->status_code) )!=1 ) {
67 printf("Malformed answer\n");
68 return NULL;
69 }
70 hdr_ptr += 4;
71
72 // Get the reason phrase
73 ptr = strstr( hdr_ptr, "\r\n" );
74 if( hdr_ptr==NULL ) {
75 printf("Malformed answer\n");
76 return NULL;
77 }
78 len = ptr-hdr_ptr;
79 http_hdr->reason_phrase = (char*)malloc(len+1);
80 if( http_hdr->reason_phrase==NULL ) {
81 printf("Memory allocation failed\n");
82 return NULL;
83 }
84 strncpy( http_hdr->reason_phrase, hdr_ptr, len );
85 http_hdr->reason_phrase[len]='\0';
86
87 // Set the position of the header separator: \r\n\r\n
88 ptr = strstr(response, "\r\n\r\n");
89 if( ptr==NULL ) {
90 printf("Malformed answer\n");
91 return NULL;
92 }
93 pos_hdr_sep = ptr-response;
94
95 hdr_ptr = strstr( response, "\r\n" )+2;
96 do {
97 ptr = strstr( hdr_ptr, "\r\n");
98 if( ptr==NULL ) {
99 printf("No CRLF found\n");
100 return NULL;
101 }
102 len = ptr-hdr_ptr;
103 field = (char*)realloc(field, len+1);
104 if( field==NULL ) {
105 printf("Memory allocation failed\n");
106 return NULL;
107 }
108 strncpy( field, hdr_ptr, len );
109 field[len]='\0';
110 http_set_field( http_hdr, field );
111 hdr_ptr = ptr+2;
112 } while( hdr_ptr<(response+pos_hdr_sep) );
113
114 if( field!=NULL ) free( field );
115
116 if( pos_hdr_sep+4<length ) {
117 // Response has data!
118 int data_length = length-(pos_hdr_sep+4);
119 http_hdr->body = (char*)malloc( data_length );
120 if( http_hdr->body==NULL ) {
121 printf("Failed to allocate memory\n");
122 return NULL;
123 }
124 memcpy( http_hdr->body, response+pos_hdr_sep+4, data_length );
125 http_hdr->body_size = data_length;
126 }
127
128 return http_hdr;
129 }
130
131 char *
132 http_get_request( HTTP_header_t *http_hdr ) {
133 char *request;
134 char *ptr;
135 int i;
136 if( http_hdr==NULL ) return NULL;
137
138 request = (char*)malloc(1024); // FIXME
139 if( request==NULL ) return NULL;
140
141 if( http_hdr->method==NULL ) http_set_method( http_hdr, "GET");
142 if( http_hdr->uri==NULL ) http_set_uri( http_hdr, "/");
143
144 ptr = request;
145 ptr += sprintf( ptr, "%s %s HTTP/1.%d\r\n", http_hdr->method, http_hdr->uri, http_hdr->http_minor_version );
146 for( i=0 ; i<http_hdr->field_nb ; i++ )
147 ptr += sprintf( ptr, "%s\r\n", http_hdr->fields[i] );
148 ptr += sprintf( ptr, "\r\n" );
149 if( http_hdr->body!=NULL ) {
150 memcpy( ptr, http_hdr->body, http_hdr->body_size );
151 }
152
153 return request;
154 }
155
156 char *
157 http_get_field( HTTP_header_t *http_hdr, const char *field_name ) {
158 if( http_hdr==NULL || field_name==NULL ) return NULL;
159 http_hdr->search_pos = 0;
160 if( http_hdr->field_search!=NULL ) free( http_hdr->field_search );
161 http_hdr->field_search = (char*)malloc(strlen(field_name)+1);
162 if( http_hdr->field_search==NULL ) {
163 printf("Memory allocation failed\n");
164 return NULL;
165 }
166 strcpy( http_hdr->field_search, field_name );
167 return http_get_next_field( http_hdr );
168 }
169
170 char *
171 http_get_next_field( HTTP_header_t *http_hdr ) {
172 char *ptr;
173 int i;
174 if( http_hdr==NULL ) return NULL;
175
176 for( i=http_hdr->search_pos ; i<http_hdr->field_nb ; i++ ) {
177 ptr = strstr( http_hdr->fields[i], ":" );
178 if( ptr==NULL ) return NULL;
179 if( !strncasecmp( http_hdr->fields[i], http_hdr->field_search, ptr-http_hdr->fields[i] ) ) {
180 ptr++; // Skip the column
181 while( ptr[0]==' ' ) ptr++; // Skip the spaces if there is some
182 http_hdr->search_pos = i+1;
183 return ptr; // return the value without the field name
184 }
185 }
186 return NULL;
187 }
188
189 void
190 http_set_field( HTTP_header_t *http_hdr, const char *field ) {
191 int pos;
192 if( http_hdr==NULL || field==NULL ) return;
193
194 pos = http_hdr->field_nb;
195
196 http_hdr->fields[pos] = (char*)malloc(strlen(field)+1);
197 if( http_hdr->fields[pos]==NULL ) {
198 printf("Memory allocation failed\n");
199 return;
200 }
201 http_hdr->field_nb++;
202 strcpy( http_hdr->fields[pos], field );
203 }
204
205 void
206 http_set_method( HTTP_header_t *http_hdr, const char *method ) {
207 if( http_hdr==NULL || method==NULL ) return;
208
209 http_hdr->method = (char*)malloc(strlen(method)+1);
210 if( http_hdr->method==NULL ) {
211 printf("Memory allocation failed\n");
212 return;
213 }
214 strcpy( http_hdr->method, method );
215 }
216
217 void
218 http_set_uri( HTTP_header_t *http_hdr, const char *uri ) {
219 if( http_hdr==NULL || uri==NULL ) return;
220
221 http_hdr->uri = (char*)malloc(strlen(uri)+1);
222 if( http_hdr->uri==NULL ) {
223 printf("Memory allocation failed\n");
224 return;
225 }
226 strcpy( http_hdr->uri, uri );
227 }
228
229 void
230 http_debug_hdr( HTTP_header_t *http_hdr ) {
231 int i;
232
233 printf("protocol: %s\n", http_hdr->protocol );
234 printf("http minor version: %d\n", http_hdr->http_minor_version );
235 printf("uri: %s\n", http_hdr->uri );
236 printf("method: %s\n", http_hdr->method );
237 printf("status code: %d\n", http_hdr->status_code );
238 printf("reason phrase: %s\n", http_hdr->reason_phrase );
239
240 printf("Fields:\n");
241 for( i=0 ; i<http_hdr->field_nb ; i++ )
242 printf(" %d - %s\n", i, http_hdr->fields[i] );
243
244 }