ib_status_t ib_bytestr_alias_mem( ib_bytestr_t **pdst, ib_mpool_t *pool, const uint8_t *data, size_t data_length ) { IB_FTRACE_INIT(); if (data == NULL) { IB_FTRACE_RET_STATUS(IB_EINVAL); } ib_status_t rc = ib_bytestr_create(pdst, pool, 0); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } /* We use flags to enforce that the user can not recover an non-const * pointer. */ (*pdst)->data = (uint8_t*)data; (*pdst)->length = data_length; (*pdst)->size = data_length; (*pdst)->flags |= IB_BYTESTR_FREADONLY; IB_FTRACE_RET_STATUS(IB_OK); }
ib_status_t ib_bytestr_dup_mem( ib_bytestr_t **pdst, ib_mpool_t *pool, const uint8_t *data, size_t data_length ) { IB_FTRACE_INIT(); assert(pdst != NULL); assert(pool != NULL); if (data == NULL && data_length != 0) { IB_FTRACE_RET_STATUS(IB_EINVAL); } ib_status_t rc = ib_bytestr_create(pdst, pool, data_length); if (rc != IB_OK) { IB_FTRACE_RET_STATUS(rc); } if (data != NULL) { assert((*pdst)->size >= data_length); memcpy(ib_bytestr_ptr(*pdst), data, data_length); (*pdst)->length = data_length; } IB_FTRACE_RET_STATUS(IB_OK); }
ib_status_t ib_bytestr_alias_mem( ib_bytestr_t **pdst, ib_mm_t mm, const uint8_t *data, size_t data_length ) { if (data == NULL && data_length > 0) { return IB_EINVAL; } ib_status_t rc = ib_bytestr_create(pdst, mm, 0); if (rc != IB_OK) { return rc; } /* We use flags to enforce that the user can not recover an non-const * pointer. */ (*pdst)->data = (uint8_t*)data; (*pdst)->length = data_length; (*pdst)->size = data_length; (*pdst)->flags |= IB_BYTESTR_FREADONLY; return IB_OK; }
ib_status_t ib_bytestr_dup_mem( ib_bytestr_t **pdst, ib_mm_t mm, const uint8_t *data, size_t data_length ) { assert(pdst != NULL); if (data == NULL && data_length != 0) { return IB_EINVAL; } ib_status_t rc = ib_bytestr_create(pdst, mm, data_length); if (rc != IB_OK) { return rc; } if (data != NULL) { assert((*pdst)->size >= data_length); memcpy(ib_bytestr_ptr(*pdst), data, data_length); (*pdst)->length = data_length; } return IB_OK; }
ib_status_t ib_parsed_req_line_create( ib_parsed_req_line_t **line, ib_mm_t mm, const char *raw, size_t raw_len, const char *method, size_t method_len, const char *uri, size_t uri_len, const char *protocol, size_t protocol_len ) { ib_status_t rc = IB_OK; ib_parsed_req_line_t *line_tmp = ib_mm_alloc(mm, sizeof(*line_tmp)); if (line_tmp == NULL) { return IB_EALLOC; } /* Record the components if available. If the components are * not available, but the raw line is, then it will be possible * to parse the components out later on. Otherwise, if there * is no component and no raw line, then set default values. */ if (method != NULL) { rc = ib_bytestr_dup_mem( &line_tmp->method, mm, (const uint8_t *)method, method_len ); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem( &line_tmp->method, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } if (uri != NULL) { rc = ib_bytestr_dup_mem( &line_tmp->uri, mm, (const uint8_t *)uri, uri_len ); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem( &line_tmp->uri, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } if (protocol != NULL) { rc = ib_bytestr_dup_mem( &line_tmp->protocol, mm, (const uint8_t *)protocol, protocol_len ); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem( &line_tmp->protocol, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } /* If no raw line is available, then create one. */ if (raw == NULL) { if (method_len + uri_len + protocol_len == 0) { rc = ib_bytestr_dup_mem( &line_tmp->raw, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } else { size_t raw_line_len; assert(method != NULL); assert(uri != NULL); /* Create a correctly sized bytestr and manually copy * the data into it. */ raw_line_len = method_len + 1 + uri_len + (protocol == NULL ? 0 : 1 + protocol_len); rc = ib_bytestr_create(&line_tmp->raw, mm, raw_line_len); if (rc != IB_OK) { return rc; } ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)method, method_len ); ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)" ", 1 ); ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)uri, uri_len ); if (protocol != NULL) { ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)" ", 1 ); ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)protocol, protocol_len ); } } } else { rc = ib_bytestr_dup_mem( &line_tmp->raw, mm, (const uint8_t *)raw, raw_len ); if (rc != IB_OK) { return rc; } } /* Commit back successfully created line. */ *line = line_tmp; return IB_OK; }
ib_status_t ib_parsed_resp_line_create( ib_parsed_resp_line_t **line, ib_mm_t mm, const char *raw, size_t raw_len, const char *protocol, size_t protocol_len, const char *status, size_t status_len, const char *msg, size_t msg_len ) { ib_status_t rc = IB_OK; ib_parsed_resp_line_t *line_tmp = ib_mm_alloc(mm, sizeof(*line_tmp)); if (line_tmp == NULL) { return IB_EALLOC; } if (protocol != NULL) { rc = ib_bytestr_dup_mem( &line_tmp->protocol, mm, (const uint8_t *)protocol, protocol_len ); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem( &line_tmp->protocol, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } if (status != NULL) { rc = ib_bytestr_dup_mem( &line_tmp->status, mm, (const uint8_t *)status, status_len ); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem( &line_tmp->status, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } if (msg != NULL) { rc = ib_bytestr_dup_mem( &line_tmp->msg, mm, (const uint8_t *)msg, msg_len ); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem( &line_tmp->msg, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } /* If no raw line is available, then create one. */ if (raw == NULL) { assert(protocol != NULL); assert(status != NULL); if (protocol_len + status_len + msg_len == 0) { rc = ib_bytestr_dup_mem( &line_tmp->raw, mm, (const uint8_t *)"", 0 ); if (rc != IB_OK) { return rc; } } else { /* Create a correctly sized bytestr and manually copy * the data into it. */ rc = ib_bytestr_create( &line_tmp->raw, mm, protocol_len + 1 + status_len + (msg == NULL ? 0 : 1 + msg_len) ); if (rc != IB_OK) { return rc; } ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)protocol, protocol_len ); ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)" ", 1 ); ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)status, status_len ); if (msg != NULL) { ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)" ", 1 ); ib_bytestr_append_mem( line_tmp->raw, (const uint8_t *)msg, msg_len ); } } } else { rc = ib_bytestr_dup_mem( &line_tmp->raw, mm, (const uint8_t *)raw, raw_len ); if (rc != IB_OK) { return rc; } } /* Commit back successfully created line. */ *line = line_tmp; return IB_OK; }
ib_status_t ib_parsed_req_line_create(ib_tx_t *tx, ib_parsed_req_line_t **line, const char *raw, size_t raw_len, const char *method, size_t method_len, const char *uri, size_t uri_len, const char *protocol, size_t protocol_len) { ib_status_t rc = IB_OK; assert(tx != NULL); assert(tx->ib != NULL); assert(tx->mp != NULL); ib_parsed_req_line_t *line_tmp = ib_mpool_alloc(tx->mp, sizeof(*line_tmp)); if ( line_tmp == NULL ) { *line = NULL; return IB_EALLOC; } /* Record the components if available. If the components are * not available, but the raw line is, then it will be possible * to parse the components out later on. Otherwise, if there * is no component and no raw line, then set default values. */ if (method != NULL) { rc = ib_bytestr_dup_mem(&line_tmp->method, tx->mp, (const uint8_t *)method, method_len); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->method, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } if (uri != NULL) { rc = ib_bytestr_dup_mem(&line_tmp->uri, tx->mp, (const uint8_t *)uri, uri_len); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->uri, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } if (protocol != NULL) { rc = ib_bytestr_dup_mem(&line_tmp->protocol, tx->mp, (const uint8_t *)protocol, protocol_len); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->protocol, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } /* If no raw line is available, then create one. */ if (raw == NULL) { if (method_len + uri_len + protocol_len == 0) { ib_log_notice_tx(tx, "Unable to generate raw request line without line " "components - using zero length request line." ); rc = ib_bytestr_dup_mem(&line_tmp->raw, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } else { size_t raw_line_len; assert(method != NULL); assert(uri != NULL); /* Create a correctly sized bytestr and manually copy * the data into it. */ raw_line_len = method_len + 1 + uri_len + (protocol == NULL ? 0 : 1 + protocol_len); rc = ib_bytestr_create(&line_tmp->raw, tx->mp, raw_line_len); if (rc != IB_OK) { return rc; } ib_log_debug_tx(tx, "Generating raw request line from components " "(length %zd).", raw_line_len); ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)method, method_len); ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)" ", 1); ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)uri, uri_len); if (protocol != NULL) { ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)" ", 1); ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)protocol, protocol_len); } } } else { rc = ib_bytestr_dup_mem(&line_tmp->raw, tx->mp, (const uint8_t *)raw, raw_len); if (rc != IB_OK) { return rc; } /* Now, if all components are missing, then parse them out * from the raw line. If only some are missing, then * do not assume anything is parsable. * * NOTE: This is a strict HTTP parser and assumes single * space (0x20) component separators. Better is to * have the server parse the components properly. */ if ((method == NULL) && (uri == NULL) && (protocol == NULL)) { uint8_t *raw_end = (uint8_t *)(raw + raw_len) - 1; uint8_t *ptr = (uint8_t *)raw; const uint8_t *parsed_field = ptr; ib_log_debug_tx(tx, "Parsing raw request line into components."); /* Parse the method. */ while (ptr <= raw_end) { if (*ptr == ' ') { break; } ++ptr; } rc = ib_bytestr_dup_mem(&line_tmp->method, tx->mp, parsed_field, (ptr - parsed_field)); if (rc != IB_OK) { return rc; } /* Parse the uri. */ parsed_field = ++ptr; while (ptr <= raw_end) { if (*ptr == ' ') { break; } ++ptr; } rc = ib_bytestr_dup_mem(&line_tmp->uri, tx->mp, parsed_field, (ptr - parsed_field)); if (rc != IB_OK) { return rc; } /* Parse the protocol. */ parsed_field = ++ptr; if (parsed_field <= raw_end) { rc = ib_bytestr_dup_mem(&line_tmp->protocol, tx->mp, parsed_field, (raw_end - parsed_field) + 1); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->protocol, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } } } /* Commit back successfully created line. */ *line = line_tmp; return IB_OK; }
ib_status_t ib_parsed_resp_line_create(ib_tx_t *tx, ib_parsed_resp_line_t **line, const char *raw, size_t raw_len, const char *protocol, size_t protocol_len, const char *status, size_t status_len, const char *msg, size_t msg_len) { ib_status_t rc = IB_OK; assert(tx != NULL); assert(tx->ib != NULL); assert(tx->mp != NULL); ib_parsed_resp_line_t *line_tmp = ib_mpool_alloc(tx->mp, sizeof(*line_tmp)); if (line_tmp == NULL) { *line = NULL; return IB_EALLOC; } if (protocol != NULL) { rc = ib_bytestr_dup_mem(&line_tmp->protocol, tx->mp, (const uint8_t *)protocol, protocol_len); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->protocol, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } if (status != NULL) { rc = ib_bytestr_dup_mem(&line_tmp->status, tx->mp, (const uint8_t *)status, status_len); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->status, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } if (msg != NULL) { rc = ib_bytestr_dup_mem(&line_tmp->msg, tx->mp, (const uint8_t *)msg, msg_len); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->msg, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } /* If no raw line is available, then create one. */ if (raw == NULL) { assert(protocol != NULL); assert(status != NULL); if (protocol_len + status_len + msg_len == 0) { rc = ib_bytestr_dup_mem(&line_tmp->raw, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } else { /* Create a correctly sized bytestr and manually copy * the data into it. */ rc = ib_bytestr_create(&line_tmp->raw, tx->mp, protocol_len + 1 + status_len + (msg == NULL ? 0 : 1 + msg_len)); if (rc != IB_OK) { return rc; } ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)protocol, protocol_len); ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)" ", 1); ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)status, status_len); if (msg != NULL) { ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)" ", 1); ib_bytestr_append_mem(line_tmp->raw, (const uint8_t *)msg, msg_len); } } } else { rc = ib_bytestr_dup_mem(&line_tmp->raw, tx->mp, (const uint8_t *)raw, raw_len); if (rc != IB_OK) { return rc; } /* Now, if all components are missing, then parse them out * from the raw line. If only some are missing, then * do not assume anything is parsable. * * NOTE: This is a strict HTTP parser and assumes single * space (0x20) component separators. Better is to * have the server parse the components properly. */ if ((protocol == NULL) && (status == NULL) && (msg == NULL)) { uint8_t *raw_end = (uint8_t *)(raw + raw_len) - 1; uint8_t *ptr = (uint8_t *)raw; const uint8_t *parsed_field = ptr; ib_log_debug_tx(tx, "Parsing raw response line into components."); /* Parse the protocol. */ while (ptr <= raw_end) { if (*ptr == ' ') { break; } ++ptr; } rc = ib_bytestr_dup_mem(&line_tmp->protocol, tx->mp, parsed_field, (ptr - parsed_field)); if (rc != IB_OK) { return rc; } /* Parse the status. */ parsed_field = ++ptr; while (ptr <= raw_end) { if (*ptr == ' ') { break; } ++ptr; } rc = ib_bytestr_dup_mem(&line_tmp->status, tx->mp, parsed_field, (ptr - parsed_field)); if (rc != IB_OK) { return rc; } /* Parse the message. */ parsed_field = ++ptr; if (parsed_field <= raw_end) { rc = ib_bytestr_dup_mem(&line_tmp->msg, tx->mp, parsed_field, (raw_end - parsed_field) + 1); if (rc != IB_OK) { return rc; } } else { rc = ib_bytestr_dup_mem(&line_tmp->msg, tx->mp, (const uint8_t *)"", 0); if (rc != IB_OK) { return rc; } } } } /* Commit back successfully created line. */ *line = line_tmp; return IB_OK; }