870
|
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 }
|