00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <time.h>
00039 #ifndef _WIN32
00040 #include <unistd.h>
00041 #include "config.h"
00042 #else
00043 #include "winconfig.h"
00044 #endif
00045 #include "include/connection.h"
00046 #include "include/mtp_http.h"
00047 #include "include/macros.h"
00048 #include "include/mc_error.h"
00049 #include "include/message.h"
00050 #include "include/dynstring.h"
00051
00052 int
00053 mtp_http_Destroy(mtp_http_p http)
00054 {
00055 int i;
00056 #define SAFE_FREE(elem) \
00057 if(elem) \
00058 free(elem)
00059
00060 SAFE_FREE(http->http_version);
00061 SAFE_FREE(http->host);
00062 SAFE_FREE(http->return_code);
00063 SAFE_FREE(http->target);
00064 SAFE_FREE(http->date);
00065 SAFE_FREE(http->server);
00066 SAFE_FREE(http->accept_ranges);
00067 SAFE_FREE(http->content_length);
00068 SAFE_FREE(http->connection);
00069 SAFE_FREE(http->content_type);
00070 SAFE_FREE(http->user_agent);
00071 if(http->content != NULL) {
00072 for(i = 0; i < http->message_parts; i++) {
00073 SAFE_FREE(http->content[i].content_type);
00074 SAFE_FREE(http->content[i].data);
00075 }
00076 }
00077 SAFE_FREE(http->content);
00078 SAFE_FREE(http->boundary);
00079 SAFE_FREE(http);
00080 #undef SAFE_FREE
00081 return 0;
00082 }
00083
00084 mtp_http_p
00085 mtp_http_New(void)
00086 {
00087 mtp_http_p http;
00088 http = (mtp_http_p)malloc(sizeof(mtp_http_t));
00089 CHECK_NULL(http, exit(0););
00090 memset(http, 0, sizeof(mtp_http_t));
00091 http->content = NULL;
00092 return http;
00093 }
00094
00095 int
00096 mtp_http_InitializeFromConnection
00097 (
00098 mtp_http_p http,
00099 connection_p connection
00100 )
00101 {
00102 int i=1;
00103 int n;
00104 char *message_string;
00105 char *buffer;
00106 int message_size = 0;
00107
00108 buffer = (char*) malloc(sizeof(char) * (SOCKET_INPUT_SIZE + 1));
00109 CHECK_NULL(buffer, exit(0););
00110 message_string = (char*) malloc(sizeof(char) * (SOCKET_INPUT_SIZE + 1));
00111 CHECK_NULL(message_string, exit(0););
00112 message_string[0] = '\0';
00113 buffer[0] = '\0';
00114
00115 while(1){
00116 #ifndef _WIN32
00117 n = recvfrom(connection->clientfd,
00118 (void *) buffer,
00119 (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00120 0,
00121 (struct sockaddr *) 0,
00122 (socklen_t *) 0);
00123 #else
00124 n = recvfrom(connection->clientfd,
00125 (void *) buffer,
00126 (size_t) sizeof(char)*SOCKET_INPUT_SIZE,
00127 0,
00128 (struct sockaddr *) 0,
00129 0);
00130 #endif
00131 if (n < 0) {
00132 free(buffer);
00133 return MC_ERR_CONNECT;
00134 }
00135 else if (n == 0 || n < SOCKET_INPUT_SIZE) {
00136 if (n != 0) {
00137 buffer[n] = '\0';
00138 strcat(message_string, buffer);
00139 }
00140 free(buffer);
00141 if(mtp_http_Parse(http, message_string)) {
00142
00143 buffer = malloc
00144 (
00145 sizeof(char) *
00146 (
00147 strlen
00148 (
00149 "HTTP/1.0 503 Service Unavailable\r\nConnection: Close\r\n\r\nMobile C"
00150 )+1
00151 )
00152 );
00153 strcpy
00154 (
00155 buffer,
00156 "HTTP/1.0 503 Service Unavailable\r\nConnection: Close\r\n\r\nMobile C"
00157 );
00158 send
00159 (
00160 connection->clientfd,
00161 (void*)buffer,
00162 sizeof(char)*(strlen(buffer)),
00163 0
00164 );
00165 free(message_string);
00166 free(buffer);
00167 return ERR;
00168 } else {
00169 free(message_string);
00170 }
00171
00172 if (n < SOCKET_INPUT_SIZE) {
00173 buffer = strdup("HTTP/1.0 200 OK\r\nConnection: Close\r\n\r\nMobile C");
00174 send(
00175 connection->clientfd,
00176 (void*)buffer,
00177 sizeof(char)*strlen(buffer),
00178 0 );
00179 #ifdef _WIN32
00180 closesocket(connection->clientfd);
00181 #else
00182 close(connection->clientfd);
00183 #endif
00184 free(buffer);
00185 }
00186 break;
00187 } else {
00188 message_size += n;
00189 buffer[n] = '\0';
00190 i++;
00191 strcat(message_string, buffer);
00192 message_string = realloc
00193 (
00194 message_string,
00195 sizeof(char) * (SOCKET_INPUT_SIZE+1) * i
00196 );
00197 CHECK_NULL(message_string, exit(0););
00198 buffer[0] = '\0';
00199 if (!strcmp
00200 (
00201 message_string + message_size - 4,
00202 "\r\n\r\n"
00203 )
00204 )
00205 break;
00206 }
00207 }
00208 return 0;
00209 }
00210
00211 const char* http_GetExpression(const char* string, char** expr)
00212 {
00213 int i;
00214 int j;
00215 int success_flag = 0;
00216 const char* next_expr_ptr;
00217
00218 if(
00219 (string[0] == '\n') ||
00220 (string[0] == '\r' && string[1] == '\n')
00221 )
00222 {
00223 for(i = 0; string[i] == '\n' || string[i] == '\r'; i++);
00224 *expr = NULL;
00225 return string+i;
00226 }
00227
00228 for(i = 0;string[i] != '\0';i++) {
00229 if (
00230 (
00231 (string[i] == '\r') &&
00232 (string[i+1] == '\n') &&
00233 (string[i+2] != '\t') &&
00234 (string[i+2] != ' ')
00235 )
00236 ||
00237 (
00238 string[i] == '\n' &&
00239 string[i+1] != '\t' &&
00240 string[i+2] != ' '
00241 )
00242 )
00243 {
00244 success_flag = 1;
00245 break;
00246 }
00247 }
00248 if(success_flag)
00249 {
00250 *expr = (char*)malloc
00251 (
00252 sizeof(char) * (i+1)
00253 );
00254 for(j = 0; j < i; j++) {
00255 (*expr)[j] = string[j];
00256 }
00257 (*expr)[j] = '\0';
00258 next_expr_ptr = &(string[i]);
00259 if(next_expr_ptr[0] == '\r' && next_expr_ptr[1] == '\n') {
00260 next_expr_ptr += 2;
00261 } else if (next_expr_ptr[0] == '\n') {
00262 next_expr_ptr++;
00263 }
00264 return next_expr_ptr;
00265 } else {
00266 return NULL;
00267 }
00268 }
00269
00270 int http_ParseExpression(
00271 const char* expression_string,
00272 char** name,
00273 char** value
00274 )
00275 {
00276 int i=0;
00277 const char* tmp;
00278 const char* charptr;
00279 if(expression_string == NULL) {
00280 *name = NULL;
00281 *value = NULL;
00282 return MC_ERR_PARSE;
00283 }
00284 tmp = expression_string;
00285 if (tmp == NULL || (!strncmp(tmp, "\r\n", 2)) || (!strncmp(tmp, "\n", 1))) {
00286 *name = NULL;
00287 *value = NULL;
00288 return MC_ERR_PARSE;
00289 }
00290 for(; *tmp!=':' && *tmp!='\0'; tmp++)
00291 i++;
00292 if(*tmp == '\0') {
00293 *name = NULL;
00294 *value = NULL;
00295 return MC_ERR_PARSE;
00296 }
00297 *name = (char*)malloc
00298 (
00299 sizeof(char) * (i+1)
00300 );
00301 CHECK_NULL(*name, exit(0););
00302 charptr = expression_string;
00303 i=0;
00304 while(charptr != tmp) {
00305 (*name)[i] = *charptr;
00306 i++;
00307 charptr++;
00308 }
00309 (*name)[i] = '\0';
00310
00311 tmp++;
00312 while
00313 (
00314 (*tmp == ' ') ||
00315 (*tmp == '\t')
00316 )
00317 tmp++;
00318
00319 *value = (char*)malloc
00320 (
00321 sizeof(char) *
00322 (strlen(tmp) + 1)
00323 );
00324 CHECK_NULL(*value, exit(0););
00325 strcpy(*value, tmp);
00326 return MC_SUCCESS;
00327 }
00328
00329 int
00330 mtp_http_Parse(struct mtp_http_s* http, const char* string)
00331 {
00332 const char* line = NULL;
00333 char* expr = NULL;
00334 char* name = NULL;
00335 char* value = NULL;
00336 char* tmp;
00337 char* tmp2;
00338 int i;
00339
00340 int err_code = 0;
00341
00342 line = string;
00343 line = http_ParseHeader
00344 (
00345 http,
00346 line
00347 );
00348 do
00349 {
00350 line = http_GetExpression
00351 (
00352 line,
00353 &expr
00354 );
00355
00356 err_code = http_ParseExpression
00357 (
00358 expr,
00359 &name,
00360 &value
00361 );
00362 if
00363 (
00364 (name == NULL) ||
00365 (value == NULL)
00366 )
00367 {
00368 if (expr != NULL) {
00369 free(expr);
00370 }
00371 break;
00372 }
00373 #define HTTP_PARSE_EXPR( parse_name, struct_name ) \
00374 if ( !strcmp(name, parse_name) ) { \
00375 http->struct_name = (char*)malloc \
00376 ( \
00377 sizeof(char) * \
00378 (strlen(value)+1) \
00379 ); \
00380 strcpy(http->struct_name, value); \
00381 } else
00382
00383 HTTP_PARSE_EXPR( "Host", host )
00384 HTTP_PARSE_EXPR( "Date", date )
00385 HTTP_PARSE_EXPR( "Server", server )
00386 HTTP_PARSE_EXPR( "Accept-Ranges", accept_ranges )
00387 HTTP_PARSE_EXPR( "Content-Length", content_length)
00388 HTTP_PARSE_EXPR( "Connection", connection )
00389 HTTP_PARSE_EXPR( "Content-Type", content_type)
00390 HTTP_PARSE_EXPR( "User-Agent", user_agent)
00391 HTTP_PARSE_EXPR( "Cache-Control", cache_control)
00392 HTTP_PARSE_EXPR( "MIME-Version", mime_version)
00393 HTTP_PARSE_EXPR( "Mime-Version", mime_version)
00394 {
00395 fprintf(stderr, "Warning: Unknown http name: %s. %s:%d\n",
00396 name, __FILE__, __LINE__);
00397 }
00398 #undef HTTP_PARSE_EXPR
00399
00400 #define SAFE_FREE( object ) \
00401 if(object) free(object); \
00402 object = NULL
00403
00404 SAFE_FREE(expr);
00405 SAFE_FREE(name);
00406 SAFE_FREE(value);
00407 #undef SAFE_FREE
00408
00409 } while(line != NULL && err_code == MC_SUCCESS);
00410
00411
00412 if(
00413 http->content_type != NULL &&
00414 !strncmp(
00415 http->content_type,
00416 "multipart/mixed",
00417 strlen("multipart/mixed")
00418 )
00419 )
00420 {
00421 tmp = strstr(http->content_type, "boundary=");
00422 tmp += strlen("boundary=.");
00423 tmp2 = strchr(tmp, '\"');
00424 http->boundary = (char*)malloc(sizeof(char) * (tmp2 - tmp + 3));
00425
00426 http->boundary[0] = '-';
00427 http->boundary[1] = '-';
00428 for (i = 0; tmp != tmp2; i++, tmp++) {
00429 http->boundary[i+2] = *tmp;
00430 }
00431 http->boundary[i+2] = '\0';
00432
00433
00434 tmp = (char*)line;
00435 http->message_parts = 0;
00436 while((tmp = strstr(tmp, http->boundary))) {
00437 http->message_parts++;
00438 tmp++;
00439 }
00440 http->message_parts--;
00441 } else {
00442 http->boundary = NULL;
00443 http->message_parts = 1;
00444 }
00445
00446 if (http->message_parts == 1) {
00447 http->content = (struct mtp_http_content_s*)malloc(sizeof(struct mtp_http_content_s));
00448
00449 if (line != NULL) {
00450 http->content->data = (void*)malloc
00451 (
00452 sizeof(char) *
00453 (strlen(line)+1)
00454 );
00455 strcpy((char*)http->content->data, line);
00456 if (http->content_type != NULL) {
00457 http->content->content_type = strdup(http->content_type);
00458 }
00459 }
00460 } else {
00461 http->content = (struct mtp_http_content_s*)malloc(
00462 sizeof(struct mtp_http_content_s) * http->message_parts );
00463 memset(http->content, 0, sizeof(struct mtp_http_content_s) * http->message_parts);
00464
00465 line = strstr(line, http->boundary);
00466 line += strlen(http->boundary);
00467 line = strchr(line, '\n');
00468 line++;
00469 for(i = 0; i < http->message_parts; i++) {
00470
00471
00472
00473
00474
00475
00476
00477 tmp = strstr(line + strlen(http->boundary), http->boundary);
00478
00479 do{
00480
00481
00482 line = http_GetExpression
00483 (
00484 line,
00485 &expr
00486 );
00487
00488 err_code = http_ParseExpression
00489 (
00490 expr,
00491 &name,
00492 &value
00493 );
00494 if
00495 (
00496 (name == NULL) ||
00497 (value == NULL)
00498 )
00499 {
00500 if (expr != NULL) {
00501 free(expr);
00502 }
00503 break;
00504 }
00505 if (!strcmp(name, "Content-Type")) {
00506 http->content[i].content_type = (char*)malloc(
00507 sizeof(char) * (strlen(value)+1));
00508 strcpy(http->content[i].content_type, value);
00509 }
00510
00511
00512 if (expr != NULL) {
00513 free(expr);
00514 expr = NULL;
00515 }
00516 if (name != NULL) {
00517 free(name);
00518 name = NULL;
00519 }
00520 if (value != NULL) {
00521 free(value);
00522 value = NULL;
00523 }
00524 } while(line != NULL && err_code == MC_SUCCESS);
00525
00526 http->content[i].data = (void*)malloc(tmp-line+sizeof(char));
00527 memcpy(http->content[i].data, line, tmp-line);
00528 ((char*)http->content[i].data)[tmp-line] = '\0';
00529
00530 line = tmp + strlen(http->boundary);
00531 line = strchr(line, '\n');
00532 line++;
00533 }
00534 }
00535 if (
00536 (http->http_performative == HTTP_POST) ||
00537 (http->http_performative == HTTP_PUT) ||
00538 (http->http_performative == HTTP_RESPONSE)
00539 )
00540 return 0;
00541 else
00542 return 1;
00543 }
00544
00545 const char* http_ParseHeader(
00546 mtp_http_p http,
00547 const char* string )
00548 {
00549 const char* cur;
00550 char* token;
00551 char* tmp = NULL;
00552 char* target;
00553 int len;
00554
00555 cur = string;
00556 cur = http_GetToken(cur, &token);
00557 if (token == NULL) {
00558 return NULL;
00559 }
00560 if (!strcmp(token, "GET")) {
00561 http->http_performative = HTTP_GET;
00562 cur = http_GetToken(cur, &tmp);
00563
00564 if(tmp) free(tmp);
00565 } else if(!strcmp(token, "HEAD")) {
00566
00567 http->http_performative = HTTP_HEAD;
00568 } else if(!strcmp(token, "POST")) {
00569 http->http_performative = HTTP_POST;
00570 cur = http_GetToken(cur, &tmp);
00571 if(tmp != NULL) {
00572 if(!strncmp(tmp, "http://",7)) {
00573 target = strchr(tmp+7, (int)'/');
00574 } else {
00575 target = strchr(tmp, (int)'/');
00576 }
00577 if (target == NULL)
00578 target = tmp;
00579 http->target = (char*) malloc(sizeof(char) * (strlen(target)+1));
00580 strcpy(http->target, target);
00581 free(tmp);
00582 }
00583 } else if(!strcmp(token, "PUT")) {
00584 http->http_performative = HTTP_PUT;
00585 cur = http_GetToken(cur, &tmp);
00586 if (tmp != NULL) {
00587 http->target = (char*)malloc(sizeof(char)*(strlen(tmp)+1));
00588 strcpy(http->target, tmp);
00589 free(tmp);
00590 }
00591 } else if(!strcmp(token, "DELETE")) {
00592 http->http_performative = HTTP_DELETE;
00593 } else if(!strcmp(token, "TRACE")) {
00594 http->http_performative = HTTP_TRACE;
00595 } else if(!strcmp(token, "OPTIONS")) {
00596 http->http_performative = HTTP_OPTIONS;
00597 } else if(!strcmp(token, "CONNECT")) {
00598 http->http_performative = HTTP_CONNECT;
00599 } else if(!strncmp(token, "HTTP/", 5)) {
00600
00601 http->http_performative = HTTP_RESPONSE;
00602
00603 free(token);
00604 cur = http_GetToken(cur, &token);
00605 sscanf(token, "%d", &http->response_code);
00606
00607 len = strstr(cur, "\r\n") - 1;
00608 http->response_string = malloc(
00609 sizeof(char) * (len +1) );
00610 strncpy(
00611 http->response_string,
00612 cur,
00613 len );
00614 http->response_string[len] = '\0';
00615 } else {
00616
00617
00618 http->http_performative = HTTP_PERFORMATIVE_UNDEF;
00619 }
00620 free(token);
00621 cur = string;
00622 while(*cur != '\0') {
00623 if(*cur == '\n') {
00624 while (*cur == '\n' || *cur == '\r' || *cur == ' ')
00625 cur++;
00626 break;
00627 }
00628 cur++;
00629 }
00630 return cur;
00631 }
00632
00633 const char*
00634 http_GetToken(const char* string, char** token)
00635 {
00636 const char* cur;
00637 const char* begin;
00638 char* itr;
00639
00640 cur = string;
00641
00642 if (string[0] == '\r' && string[1] == '\n') {
00643 *token = NULL;
00644 return NULL;
00645 }
00646
00647 while(*cur == ' ' || *cur == '\t' || *cur == '\r' || *cur == '\n') cur++;
00648
00649 begin = cur;
00650 while(*cur != '\0') {
00651 cur++;
00652 if (*cur == ' ' || *cur == '\t' || *cur == '\r' || *cur == '\n')
00653 break;
00654 }
00655 cur--;
00656 *token = (char*)malloc(cur - begin + 4*sizeof(char));
00657 itr = *token;
00658 while (begin <= cur) {
00659 *itr = *begin;
00660 itr++;
00661 begin++;
00662 }
00663 *itr='\0';
00664 return cur+1;
00665 }
00666
00667 int mtp_http_ParseResponse(struct mtp_http_s* http, const char* string)
00668 {
00669
00670 }
00671
00672 int
00673 mtp_http_ComposeMessage(message_p message)
00674 {
00675 char* http_header;
00676 char* tmp;
00677 char buf[20];
00678 if (message->isHTTP) {
00679
00680 return 0;
00681 }
00682
00683 http_header = (char*)malloc
00684 (
00685 sizeof(char) * (1400 + strlen(message->to_address))
00686 );
00687 http_header[0] = '\0';
00688 strcat(http_header, "POST /");
00689 strcat(http_header, message->target);
00690 strcat(http_header, " HTTP/1.0\r\n");
00691 strcat(http_header, "User-Agent: MobileC/");
00692 strcat(http_header, PACKAGE_VERSION);
00693 strcat(http_header, "\r\n");
00694 strcat(http_header, "Host: ");
00695 strcat(http_header, message->to_address);
00696 strcat(http_header, "\r\n");
00697 strcat(http_header, "Content-Type: text/plain\r\n");
00698 strcat(http_header, "Connection: Close\r\n");
00699 strcat(http_header, "Content-Length: ");
00700 sprintf(buf, "%d", strlen(message->message_body) + 1);
00701 strcat(http_header, buf);
00702 strcat(http_header, "\r\n\r\n");
00703
00704 tmp = (char*)malloc
00705 (
00706 sizeof(char) *
00707 (strlen(http_header) + strlen(message->message_body) + 1)
00708 );
00709 tmp[0] = '\0';
00710 strcpy(tmp, http_header);
00711 strcat(tmp, message->message_body);
00712 free(message->message_body);
00713 message->message_body = tmp;
00714 free(http_header);
00715 return MC_SUCCESS;
00716 }
00717
00718 struct message_s*
00719 mtp_http_CreateMessage(
00720 mtp_http_t* mtp_http,
00721 char* hostname,
00722 int port)
00723 {
00724 int i;
00725 int num;
00726 char buf[30];
00727 char boundary[30];
00728 message_t* message;
00729 dynstring_t* http_header;
00730 dynstring_t* http_body;
00731 http_header = dynstring_New();
00732 http_body = dynstring_New();
00733 dynstring_Append(http_header, "POST /");
00734 dynstring_Append(http_header, mtp_http->target);
00735 dynstring_Append(http_header, " HTTP/1.1\r\n");
00736 dynstring_Append(http_header, "User-Agent: MobileC/");
00737 dynstring_Append(http_header, PACKAGE_VERSION);
00738 dynstring_Append(http_header, "\r\n");
00739 dynstring_Append(http_header, "Host: ");
00740 dynstring_Append(http_header, mtp_http->host);
00741 dynstring_Append(http_header, ":");
00742 sprintf(buf, "%d", port);
00743 dynstring_Append(http_header, buf);
00744 dynstring_Append(http_header, "\r\n");
00745 dynstring_Append(http_header, "Cache-Control: no-cache\r\n");
00746 dynstring_Append(http_header, "Mime-Version: 1.0\r\n");
00747
00748
00749
00750 if(mtp_http->message_parts == 1) {
00751 dynstring_Append(http_header, "Content-Type: text/plain\r\n");
00752 dynstring_Append(http_header, "Content-Length: ");
00753 sprintf(buf, "%d", strlen((char*)mtp_http->content[0].data));
00754 dynstring_Append(http_header, buf);
00755 dynstring_Append(http_header, "\r\n\r\n");
00756 dynstring_Append(http_header, (char*)mtp_http->content[0].data);
00757 } else {
00758
00759 srand(time(NULL));
00760 strcpy(boundary, "--");
00761 for(i = 2; i < 26; i++) {
00762 num = rand() % 36;
00763 if(num < 10) {
00764 boundary[i] = (char)(48 + num);
00765 } else {
00766 boundary[i] = (char)( (num-10)+65);
00767 }
00768 }
00769 boundary[i] = '\0';
00770
00771
00772
00773 dynstring_Append(http_body, "This is not part of the MIME multipart encoded message.\r\n");
00774 for(i = 0; i<mtp_http->message_parts; i++) {
00775 dynstring_Append(http_body, boundary);
00776 dynstring_Append(http_body, "\r\nContent-Type: ");
00777 dynstring_Append(http_body, mtp_http->content[i].content_type);
00778 dynstring_Append(http_body, "\r\n\r\n");
00779 dynstring_Append(http_body, (char*)mtp_http->content[i].data);
00780 dynstring_Append(http_body, "\r\n");
00781 }
00782
00783 dynstring_Append(http_body, boundary);
00784 dynstring_Append(http_body, "--");
00785 dynstring_Append(http_body, "\r\n\r\n");
00786
00787
00788 dynstring_Append(http_header, "Content-Length: ");
00789 sprintf(buf, "%d", http_body->len-2 );
00790 dynstring_Append(http_header, buf);
00791 dynstring_Append(http_header, "\r\n");
00792 dynstring_Append(http_header, "Content-Type: multipart/mixed ; boundary=\"");
00793 dynstring_Append(http_header, boundary+2);
00794 dynstring_Append(http_header, "\"\r\n");
00795
00796 }
00797 dynstring_Append(http_header, "Connection: Close\r\n\r\n");
00798 message = message_New();
00799 message->to_address = (char*)malloc(
00800 sizeof(char) * (strlen(hostname)+15) );
00801 sprintf(message->to_address, "%s:%d", hostname, port);
00802 message->message_body = (char*) malloc(
00803 sizeof(char) * (http_header->len + http_body->len + 1));
00804 strcpy(message->message_body, http_header->message);
00805 strcat(message->message_body, http_body->message);
00806 dynstring_Destroy(http_header);
00807 dynstring_Destroy(http_body);
00808 message->isHTTP = 1;
00809 return message;
00810 }
00811