various fixes for object_get

This commit is contained in:
John Jones 2017-09-25 17:56:10 -05:00
parent 630985c698
commit 5bcd3a99f2
8 changed files with 96 additions and 41 deletions

View file

@ -566,25 +566,27 @@ void *api_connection_thread (void *ptr)
char* response_text = NULL; char* response_text = NULL;
if (!ipfs_core_http_request_process(params->this_node, http_request, &response_text)) { if (!ipfs_core_http_request_process(params->this_node, http_request, &response_text)) {
libp2p_logger_error("api", "ipfs_core_http_request_process returned false.\n"); libp2p_logger_error("api", "ipfs_core_http_request_process returned false.\n");
// TODO: Handle this condition // 404
write_str(s, HTTP_404);
} else {
// now send the results
snprintf(resp, sizeof(resp), "%s 200 OK\r\n" \
"Content-Type: application/json\r\n"
"Server: c-ipfs/0.0.0-dev\r\n"
"X-Chunked-Output: 1\r\n"
"Connection: close\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"%x\r\n"
"%s\r\n"
"0\r\n\r\n"
,req.buf + req.http_ver, strlen(response_text), response_text);
if (response_text != NULL)
free(response_text);
write_str (s, resp);
libp2p_logger_debug("api", "resp = {\n%s\n}\n", resp);
} }
ipfs_core_http_request_free(http_request); ipfs_core_http_request_free(http_request);
// now send the results
snprintf(resp, sizeof(resp), "%s 200 OK\r\n" \
"Content-Type: application/json\r\n"
"Server: c-ipfs/0.0.0-dev\r\n"
"X-Chunked-Output: 1\r\n"
"Connection: close\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"%x\r\n"
"%s\r\n"
"0\r\n\r\n"
,req.buf + req.http_ver, strlen(response_text), response_text);
if (response_text != NULL)
free(response_text);
write_str (s, resp);
libp2p_logger_debug("api", "resp = {\n%s\n}\n", resp);
} else { } else {
// uh oh... something went wrong converting to the HttpRequest struct // uh oh... something went wrong converting to the HttpRequest struct
libp2p_logger_error("api", "Unable to build HttpRequest struct.\n"); libp2p_logger_error("api", "Unable to build HttpRequest struct.\n");

View file

@ -1,9 +1,12 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <curl/curl.h> #include <curl/curl.h>
#include "libp2p/os/memstream.h"
#include "libp2p/utils/vector.h" #include "libp2p/utils/vector.h"
#include "libp2p/utils/logger.h" #include "libp2p/utils/logger.h"
#include "ipfs/cid/cid.h"
#include "ipfs/core/http_request.h" #include "ipfs/core/http_request.h"
#include "ipfs/importer/exporter.h"
#include "ipfs/namesys/resolver.h" #include "ipfs/namesys/resolver.h"
#include "ipfs/namesys/publisher.h" #include "ipfs/namesys/publisher.h"
@ -125,6 +128,16 @@ int ipfs_core_http_process_object(struct IpfsNode* local_node, struct HttpReques
int retVal = 0; int retVal = 0;
if (strcmp(request->sub_command, "get") == 0) { if (strcmp(request->sub_command, "get") == 0) {
// do an object_get // do an object_get
if (request->arguments->total == 1) {
char* hash = (char*)libp2p_utils_vector_get(request->arguments, 0);
struct Cid* cid;
ipfs_cid_decode_hash_from_base58(hash, strlen(hash), &cid);
size_t size;
FILE* response_file = open_memstream(response, &size);
retVal = ipfs_exporter_object_cat_to_file(local_node, cid->hash, cid->hash_length, response_file);
ipfs_cid_free(cid);
fclose(response_file);
}
} }
return retVal; return retVal;
} }
@ -297,7 +310,10 @@ int ipfs_core_http_request_get(struct IpfsNode* local_node, struct HttpRequest*
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
if (res == CURLE_OK) { if (res == CURLE_OK) {
*result = s.ptr; if (strcmp(s.ptr, "404 page not found") != 0)
*result = s.ptr;
else
res = -1;
} else { } else {
libp2p_logger_error("http_request", "Results of [%s] returned failure. Return value: %d.\n", url, res); libp2p_logger_error("http_request", "Results of [%s] returned failure. Return value: %d.\n", url, res);
} }

View file

@ -3,6 +3,8 @@
#include <pthread.h> #include <pthread.h>
#include "ipfs/cid/cid.h" #include "ipfs/cid/cid.h"
#include "ipfs/core/http_request.h"
#include "ipfs/importer/exporter.h"
#include "ipfs/merkledag/merkledag.h" #include "ipfs/merkledag/merkledag.h"
#include "ipfs/merkledag/node.h" #include "ipfs/merkledag/node.h"
#include "ipfs/repo/fsrepo/fs_repo.h" #include "ipfs/repo/fsrepo/fs_repo.h"
@ -32,8 +34,9 @@ int ipfs_exporter_get_node(struct IpfsNode* local_node, const unsigned char* has
if (local_node->routing->GetValue(local_node->routing, hash, hash_size, (void**)&buffer, &buffer_size)) { if (local_node->routing->GetValue(local_node->routing, hash, hash_size, (void**)&buffer, &buffer_size)) {
libp2p_logger_debug("exporter", "get_node got a value. Converting it to a HashtableNode\n"); libp2p_logger_debug("exporter", "get_node got a value. Converting it to a HashtableNode\n");
// unprotobuf // unprotobuf
if (ipfs_hashtable_node_protobuf_decode(buffer, buffer_size, result)) { if (!ipfs_hashtable_node_protobuf_decode(buffer, buffer_size, result)) {
libp2p_logger_debug("exporter", "Conversion to HashtableNode successful\n"); libp2p_logger_debug("exporter", "Conversion to HashtableNode not successful\n");
goto exit;
} }
} else { } else {
libp2p_logger_debug("exporter", "get_node got no value. Returning false.\n"); libp2p_logger_debug("exporter", "get_node got no value. Returning false.\n");
@ -221,7 +224,9 @@ int ipfs_exporter_cat_node(struct HashtableNode* node, struct IpfsNode* local_no
// build the unixfs // build the unixfs
struct UnixFS* unix_fs; struct UnixFS* unix_fs;
ipfs_unixfs_protobuf_decode(node->data, node->data_size, &unix_fs); if (!ipfs_unixfs_protobuf_decode(node->data, node->data_size, &unix_fs)) {
return 0;
}
for(size_t i = 0LU; i < unix_fs->bytes_size; i++) { for(size_t i = 0LU; i < unix_fs->bytes_size; i++) {
fprintf(file, "%c", unix_fs->bytes[i]); fprintf(file, "%c", unix_fs->bytes[i]);
} }
@ -262,26 +267,43 @@ int ipfs_exporter_object_cat_to_file(struct IpfsNode *local_node, unsigned char*
* @param argv arguments * @param argv arguments
* @returns true(1) on success * @returns true(1) on success
*/ */
int ipfs_exporter_object_cat(int argc, char** argv) { int ipfs_exporter_object_cat(struct CliArguments* args) {
struct IpfsNode *local_node = NULL; struct IpfsNode *local_node = NULL;
char* repo_dir = NULL; char* repo_dir = NULL;
if (!ipfs_repo_get_directory(argc, argv, &repo_dir)) { if (!ipfs_repo_get_directory(args->argc, args->argv, &repo_dir)) {
fprintf(stderr, "Unable to open repo: %s\n", repo_dir); libp2p_logger_error("exporter", "Unable to open repo: %s\n", repo_dir);
return 0; return 0;
} }
if (!ipfs_node_offline_new(repo_dir, &local_node)) if (!ipfs_node_offline_new(repo_dir, &local_node)) {
libp2p_logger_error("exporter", "Unable to create new offline node based on config at %s.\n", repo_dir);
return 0; return 0;
}
if (local_node->mode == MODE_API_AVAILABLE) { if (local_node->mode == MODE_API_AVAILABLE) {
// TODO: we should use the api for this char* hash = args->argv[args->verb_index + 1];
return 0; libp2p_logger_debug("exporter", "We're attempting to use the API for this object get of %s.\n", hash);
struct HttpRequest* request = ipfs_core_http_request_new();
char* response = NULL;
request->command = "object";
request->sub_command = "get";
request->arguments = libp2p_utils_vector_new(1);
libp2p_utils_vector_add(request->arguments, hash);
int retVal = ipfs_core_http_request_get(local_node, request, &response);
if (response != NULL && strlen(response) > 0) {
fprintf(stdout, "%s", response);
free(response);
} else {
retVal = 0;
}
ipfs_core_http_request_free(request);
return retVal;
} else { } else {
// find hash libp2p_logger_debug("exporter", "API not available, using direct access.\n");
// convert hash to cid
struct Cid* cid = NULL; struct Cid* cid = NULL;
if ( ipfs_cid_decode_hash_from_base58((unsigned char*)argv[2], strlen(argv[2]), &cid) == 0) { if ( ipfs_cid_decode_hash_from_base58((unsigned char*)args->argv[args->verb_index+1], strlen(args->argv[args->verb_index+1]), &cid) == 0) {
libp2p_logger_error("exporter", "Unable to decode hash from base58 [%s]\n", args->argv[args->verb_index+1]);
return 0; return 0;
} }

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "ipfs/cmd/cli.h"
#include "ipfs/core/ipfs_node.h" #include "ipfs/core/ipfs_node.h"
/** /**
@ -32,7 +33,7 @@ int ipfs_exporter_object_get(int argc, char** argv);
* @param argv arguments * @param argv arguments
* @returns true(1) on success * @returns true(1) on success
*/ */
int ipfs_exporter_object_cat(int argc, char** argv); int ipfs_exporter_object_cat(struct CliArguments* args);
/** /**
* Retrieves the object pointed to by hash and displays the raw data * Retrieves the object pointed to by hash and displays the raw data

View file

@ -171,7 +171,7 @@ int main(int argc, char** argv) {
//ipfs_exporter_get(argc, argv); //ipfs_exporter_get(argc, argv);
//break; //break;
case (CAT): case (CAT):
ipfs_exporter_object_cat(argc, argv); ipfs_exporter_object_cat(args);
break; break;
case (DNS): case (DNS):
ipfs_dns(argc, argv); ipfs_dns(argc, argv);

View file

@ -187,6 +187,9 @@ int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length,
unsigned char* hash; unsigned char* hash;
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&hash, &hash_size, &bytes_read) == 0) if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&hash, &hash_size, &bytes_read) == 0)
goto exit; goto exit;
if (hash_size < 2) {
goto exit;
}
link->hash_size = hash_size - 2; link->hash_size = hash_size - 2;
link->hash = (unsigned char*)malloc(link->hash_size); link->hash = (unsigned char*)malloc(link->hash_size);
memcpy((char*)link->hash, (char*)&hash[2], link->hash_size); memcpy((char*)link->hash, (char*)&hash[2], link->hash_size);
@ -293,6 +296,9 @@ int ipfs_hashtable_node_protobuf_decode(unsigned char* buffer, size_t buffer_len
size_t temp_size; size_t temp_size;
struct NodeLink* temp_link = NULL; struct NodeLink* temp_link = NULL;
if (buffer_length == 0)
goto exit;
if (ipfs_hashtable_node_new(node) == 0) if (ipfs_hashtable_node_new(node) == 0)
goto exit; goto exit;
@ -315,11 +321,11 @@ int ipfs_hashtable_node_protobuf_decode(unsigned char* buffer, size_t buffer_len
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0) if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0)
goto exit; goto exit;
pos += bytes_read; pos += bytes_read;
if (ipfs_node_link_protobuf_decode(temp_buffer, temp_size, &temp_link) == 0) if (ipfs_node_link_protobuf_decode(temp_buffer, temp_size, &temp_link)) {
goto exit; ipfs_hashtable_node_add_link(*node, temp_link);
}
free(temp_buffer); free(temp_buffer);
temp_buffer = NULL; temp_buffer = NULL;
ipfs_hashtable_node_add_link(*node, temp_link);
break; break;
} }
} }

View file

@ -2,6 +2,7 @@
#include "../test_helper.h" #include "../test_helper.h"
#include "libp2p/utils/logger.h" #include "libp2p/utils/logger.h"
#include "ipfs/cmd/cli.h"
#include "ipfs/core/client_api.h" #include "ipfs/core/client_api.h"
#include "ipfs/core/daemon.h" #include "ipfs/core/daemon.h"
#include "ipfs/importer/exporter.h" #include "ipfs/importer/exporter.h"
@ -56,15 +57,15 @@ int test_core_api_object_cat() {
int thread_started1 = 0; int thread_started1 = 0;
int thread_started2 = 0; int thread_started2 = 0;
char* ipfs_path1 = "/tmp/ipfs_1"; char* ipfs_path1 = "/tmp/ipfs_1";
char* config_file1 = "config.test1"; char* config_file1 = "config.test1.wo_journal";
char* ipfs_path2 = "/tmp/ipfs_2"; char* ipfs_path2 = "/tmp/ipfs_2";
char* config_file2 = "config.test2"; char* config_file2 = "config.test2.wo_journal";
struct FSRepo* fs_repo = NULL; struct FSRepo* fs_repo = NULL;
char hash[256] = ""; char hash[256] = "";
char* args[] = {"ipfs", "--config", ipfs_path2, "cat", hash }; char* args[] = {"ipfs", "--config", ipfs_path2, "cat", hash };
// logging // logging
libp2p_logger_add_class("test_journal"); libp2p_logger_add_class("test_api");
libp2p_logger_add_class("journal"); libp2p_logger_add_class("journal");
libp2p_logger_add_class("daemon"); libp2p_logger_add_class("daemon");
libp2p_logger_add_class("online"); libp2p_logger_add_class("online");
@ -82,6 +83,7 @@ int test_core_api_object_cat() {
libp2p_logger_add_class("unixfs"); libp2p_logger_add_class("unixfs");
libp2p_logger_add_class("bitswap_engine"); libp2p_logger_add_class("bitswap_engine");
libp2p_logger_add_class("bitswap_network"); libp2p_logger_add_class("bitswap_network");
libp2p_logger_add_class("exporter");
// build 2 repos // build 2 repos
if (!drop_build_open_repo(ipfs_path1, &fs_repo, config_file1)) { if (!drop_build_open_repo(ipfs_path1, &fs_repo, config_file1)) {
@ -99,7 +101,7 @@ int test_core_api_object_cat() {
libp2p_logger_debug("test_api", "Changed the server id to %s.\n", fs_repo->config->identity->peer->id); libp2p_logger_debug("test_api", "Changed the server id to %s.\n", fs_repo->config->identity->peer->id);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
// add some files to the first repo // add a file to the first repo
uint8_t *bytes = (unsigned char*)"hello, world!\n"; uint8_t *bytes = (unsigned char*)"hello, world!\n";
char* filename = "test1.txt"; char* filename = "test1.txt";
create_file(filename, bytes, strlen((char*)bytes)); create_file(filename, bytes, strlen((char*)bytes));
@ -110,19 +112,23 @@ int test_core_api_object_cat() {
ipfs_import_file(NULL, filename, &node, local_node, &bytes_written, 0); ipfs_import_file(NULL, filename, &node, local_node, &bytes_written, 0);
memset(hash, 0, 256); memset(hash, 0, 256);
ipfs_cid_hash_to_base58(node->hash, node->hash_size, (unsigned char*)hash, 256); ipfs_cid_hash_to_base58(node->hash, node->hash_size, (unsigned char*)hash, 256);
libp2p_logger_debug("test_api", "Inserted file with hash %s.\n", hash);
ipfs_node_free(local_node); ipfs_node_free(local_node);
ipfs_hashtable_node_free(node); ipfs_hashtable_node_free(node);
libp2p_logger_debug("test_api", "*** Firing up daemons ***\n"); libp2p_logger_debug("test_api", "*** Firing up daemons ***\n");
pthread_create(&daemon_thread1, NULL, test_daemon_start, (void*)ipfs_path1); pthread_create(&daemon_thread1, NULL, test_daemon_start, (void*)ipfs_path1);
thread_started1 = 1; thread_started1 = 1;
sleep(3);
pthread_create(&daemon_thread2, NULL, test_daemon_start, (void*)ipfs_path2); pthread_create(&daemon_thread2, NULL, test_daemon_start, (void*)ipfs_path2);
thread_started2 = 1; thread_started2 = 1;
sleep(3); sleep(3);
// use a client to ask for the file on server 1 // use a client to ask for the file on server 1
if (ipfs_exporter_object_cat(5, args) == 0) { struct CliArguments* arguments = cli_arguments_new(5, args);
if (ipfs_exporter_object_cat(arguments) == 0) {
libp2p_logger_error("test_api", "ipfs_exporter_object_cat returned false.\n");
goto exit; goto exit;
} }
@ -133,6 +139,7 @@ int test_core_api_object_cat() {
pthread_join(daemon_thread1, NULL); pthread_join(daemon_thread1, NULL);
if (thread_started2) if (thread_started2)
pthread_join(daemon_thread2, NULL); pthread_join(daemon_thread2, NULL);
cli_arguments_free(arguments);
return retVal; return retVal;
} }

View file

@ -249,12 +249,13 @@ int ipfs_unixfs_protobuf_encode(const struct UnixFS* incoming, unsigned char* ou
* @param incoming the array of bytes * @param incoming the array of bytes
* @param incoming_size the length of the array * @param incoming_size the length of the array
* @param outgoing the UnixFS object * @param outgoing the UnixFS object
* @returns true(1) on success, false(0) on error
*/ */
int ipfs_unixfs_protobuf_decode(unsigned char* incoming, size_t incoming_size, struct UnixFS** outgoing) { int ipfs_unixfs_protobuf_decode(unsigned char* incoming, size_t incoming_size, struct UnixFS** outgoing) {
// short cut for nulls // short cut for nulls
if (incoming_size == 0) { if (incoming_size == 0) {
*outgoing = NULL; *outgoing = NULL;
return 1; return 0;
} }
size_t pos = 0; size_t pos = 0;