static void _mime_received_bytes(void *data, const unsigned char *bytes, int size) { int i = 0; char *id, *type, *location; mime_callback_data_t *cbdata = (mime_callback_data_t *) data; if (!cbdata) { log_error1 ("MIME transport error Called <received bytes> without initializing\n"); return; } if (!cbdata->current_part) { log_error1 ("MIME transport error Called <received bytes> without initializing\n"); return; } /* log_verbose4("Received %d bytes (%p), header_search = %d", size, data, cbdata->header_search); */ if (cbdata->header_search < 4) { /* Find \r\n\r\n in bytes */ for (i = 0; i < size; i++) { if (cbdata->header_search == 0) { if (bytes[i] == '\r') cbdata->header_search++; else { cbdata->header[cbdata->header_index++] = bytes[i]; cbdata->header_search = 0; } } else if (cbdata->header_search == 1) { if (bytes[i] == '\n') cbdata->header_search++; else { cbdata->header[cbdata->header_index++] = '\r'; cbdata->header[cbdata->header_index++] = bytes[i]; cbdata->header_search = 0; } } else if (cbdata->header_search == 2) { if (bytes[i] == '\r') cbdata->header_search++; else { cbdata->header[cbdata->header_index++] = '\r'; cbdata->header[cbdata->header_index++] = '\n'; cbdata->header[cbdata->header_index++] = bytes[i]; cbdata->header_search = 0; } } else if (cbdata->header_search == 3) { if (bytes[i] == '\n') { cbdata->header[cbdata->header_index++] = '\r'; cbdata->header[cbdata->header_index++] = '\n'; cbdata->header[cbdata->header_index++] = '\0'; cbdata->header_search = 4; cbdata->current_part->header = _mime_process_header(cbdata->header); hpairnode_dump_deep(cbdata->current_part->header); /* set id */ id = hpairnode_get(cbdata->current_part->header, HEADER_CONTENT_ID); if (id != NULL) { strcpy(cbdata->current_part->id, id); if (!strcmp(id, cbdata->root_id)) cbdata->message->root_part = cbdata->current_part; } location = hpairnode_get(cbdata->current_part->header, HEADER_CONTENT_LOCATION); if (location != NULL) { strcpy(cbdata->current_part->location, location); } type = hpairnode_get(cbdata->current_part->header, HEADER_CONTENT_TYPE); if (type != NULL) { strcpy(cbdata->current_part->content_type, type); } i++; break; } else { cbdata->header[cbdata->header_index++] = '\r'; cbdata->header[cbdata->header_index++] = '\n'; cbdata->header[cbdata->header_index++] = '\r'; cbdata->header[cbdata->header_index++] = bytes[i]; cbdata->header_search = 0; } } /* TODO (#1#): Check for cbdata->header overflow */ } /* for (i=0;i<size;i++) */ } /* if (cbdata->header_search < 4) */ if (i >= size - 1) return; /* Write remaining bytes into the file or buffer (if root) (buffer is disabled in this version) */ if (cbdata->current_fd) fwrite(&(bytes[i]), 1, size - i, cbdata->current_fd); }
herror_t mime_get_attachments(content_type_t * ctype, http_input_stream_t * in, attachments_t ** dest) { /* MIME variables */ attachments_t *mimeMessage; part_t *part, *tmp_part = NULL; char *boundary, *root_id; /* Check for MIME message */ if (!(ctype && !strcmp(ctype->type, "multipart/related"))) return herror_new("mime_get_attachments", MIME_ERROR_NOT_MIME_MESSAGE, "Not a MIME message '%s'", ctype->type); boundary = hpairnode_get(ctype->params, "boundary"); root_id = hpairnode_get(ctype->params, "start"); if (boundary == NULL) { /* TODO (#1#): Handle Error in http form */ log_error1("'boundary' not set for multipart/related"); return herror_new("mime_get_attachments", MIME_ERROR_NO_BOUNDARY_PARAM, "'boundary' not set for multipart/related"); } if (root_id == NULL) { /* TODO (#1#): Handle Error in http form */ log_error1("'start' not set for multipart/related"); return herror_new("mime_get_attachments", MIME_ERROR_NO_START_PARAM, "'start' not set for multipart/related"); } mimeMessage = mime_message_parse(in, root_id, boundary, "."); if (mimeMessage == NULL) { /* TODO (#1#): Handle Error in http form */ log_error1("MIME Parse Error"); return herror_new("mime_get_attachments", MIME_ERROR_PARSE_ERROR, "MIME Parse Error"); } /* Find root */ if (!mimeMessage->root_part) { attachments_free(mimeMessage); return herror_new("mime_get_attachments", MIME_ERROR_NO_ROOT_PART, "No root part found!"); } /* delete root_part from list */ part = mimeMessage->parts; while (part) { if (part == mimeMessage->root_part) { if (tmp_part) tmp_part->next = part->next; else mimeMessage->parts = part->next; break; } tmp_part = part; part = part->next; } *dest = mimeMessage; return H_OK; }
static hresponse_t * _hresponse_parse_header(const char *buffer) { hresponse_t *res; char *s1, *s2, *str; /* create response object */ res = hresponse_new(); /* *** parse spec *** */ /* [HTTP/1.1 | 1.2] [CODE] [DESC] */ /* stage 1: HTTP spec */ str = (char *) strtok_r((char *) buffer, " ", &s2); s1 = s2; if (str == NULL) { log_error("Parse error reading HTTP spec"); return NULL; } if (!strcmp(str, "HTTP/1.0")) res->version = HTTP_1_0; else res->version = HTTP_1_1; /* stage 2: http code */ str = (char *) strtok_r(s1, " ", &s2); s1 = s2; if (str == NULL) { log_error("Parse error reading HTTP code"); return NULL; } res->errcode = atoi(str); /* stage 3: description text */ str = (char *) strtok_r(s1, "\r\n", &s2); s1 = s2; if (str == NULL) { log_error("Parse error reading HTTP description"); return NULL; } /* res->desc = (char *) malloc(strlen(str) + 1);*/ strncpy(res->desc, str, RESPONSE_MAX_DESC_SIZE); res->desc[strlen(str)] = '\0'; /* *** parse header *** */ /* [key]: [value] */ for (;;) { str = strtok_r(s1, "\n", &s2); s1 = s2; /* check if header ends without body */ if (str == NULL) { return res; } /* check also for end of header */ if (!strcmp(str, "\r")) { break; } str[strlen(str) - 1] = '\0'; res->header = hpairnode_parse(str, ":", res->header); } /* Check Content-type */ str = hpairnode_get(res->header, HEADER_CONTENT_TYPE); if (str != NULL) res->content_type = content_type_new(str); /* return response object */ return res; }