forked from agorise/c-ipfs
various fixes for object_get
This commit is contained in:
parent
630985c698
commit
5bcd3a99f2
8 changed files with 96 additions and 41 deletions
36
core/api.c
36
core/api.c
|
@ -566,25 +566,27 @@ void *api_connection_thread (void *ptr)
|
|||
char* response_text = NULL;
|
||||
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");
|
||||
// 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);
|
||||
// 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 {
|
||||
// uh oh... something went wrong converting to the HttpRequest struct
|
||||
libp2p_logger_error("api", "Unable to build HttpRequest struct.\n");
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
#include "libp2p/os/memstream.h"
|
||||
#include "libp2p/utils/vector.h"
|
||||
#include "libp2p/utils/logger.h"
|
||||
#include "ipfs/cid/cid.h"
|
||||
#include "ipfs/core/http_request.h"
|
||||
#include "ipfs/importer/exporter.h"
|
||||
#include "ipfs/namesys/resolver.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;
|
||||
if (strcmp(request->sub_command, "get") == 0) {
|
||||
// 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;
|
||||
}
|
||||
|
@ -297,7 +310,10 @@ int ipfs_core_http_request_get(struct IpfsNode* local_node, struct HttpRequest*
|
|||
res = curl_easy_perform(curl);
|
||||
curl_easy_cleanup(curl);
|
||||
if (res == CURLE_OK) {
|
||||
*result = s.ptr;
|
||||
if (strcmp(s.ptr, "404 page not found") != 0)
|
||||
*result = s.ptr;
|
||||
else
|
||||
res = -1;
|
||||
} else {
|
||||
libp2p_logger_error("http_request", "Results of [%s] returned failure. Return value: %d.\n", url, res);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <pthread.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/node.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)) {
|
||||
libp2p_logger_debug("exporter", "get_node got a value. Converting it to a HashtableNode\n");
|
||||
// unprotobuf
|
||||
if (ipfs_hashtable_node_protobuf_decode(buffer, buffer_size, result)) {
|
||||
libp2p_logger_debug("exporter", "Conversion to HashtableNode successful\n");
|
||||
if (!ipfs_hashtable_node_protobuf_decode(buffer, buffer_size, result)) {
|
||||
libp2p_logger_debug("exporter", "Conversion to HashtableNode not successful\n");
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
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
|
||||
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++) {
|
||||
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
|
||||
* @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;
|
||||
char* repo_dir = NULL;
|
||||
|
||||
if (!ipfs_repo_get_directory(argc, argv, &repo_dir)) {
|
||||
fprintf(stderr, "Unable to open repo: %s\n", repo_dir);
|
||||
if (!ipfs_repo_get_directory(args->argc, args->argv, &repo_dir)) {
|
||||
libp2p_logger_error("exporter", "Unable to open repo: %s\n", repo_dir);
|
||||
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;
|
||||
}
|
||||
|
||||
if (local_node->mode == MODE_API_AVAILABLE) {
|
||||
// TODO: we should use the api for this
|
||||
return 0;
|
||||
char* hash = args->argv[args->verb_index + 1];
|
||||
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 {
|
||||
// find hash
|
||||
// convert hash to cid
|
||||
libp2p_logger_debug("exporter", "API not available, using direct access.\n");
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "ipfs/cmd/cli.h"
|
||||
#include "ipfs/core/ipfs_node.h"
|
||||
|
||||
/**
|
||||
|
@ -32,7 +33,7 @@ int ipfs_exporter_object_get(int argc, char** argv);
|
|||
* @param argv arguments
|
||||
* @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
|
||||
|
|
|
@ -171,7 +171,7 @@ int main(int argc, char** argv) {
|
|||
//ipfs_exporter_get(argc, argv);
|
||||
//break;
|
||||
case (CAT):
|
||||
ipfs_exporter_object_cat(argc, argv);
|
||||
ipfs_exporter_object_cat(args);
|
||||
break;
|
||||
case (DNS):
|
||||
ipfs_dns(argc, argv);
|
||||
|
|
|
@ -187,6 +187,9 @@ int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length,
|
|||
unsigned char* hash;
|
||||
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&hash, &hash_size, &bytes_read) == 0)
|
||||
goto exit;
|
||||
if (hash_size < 2) {
|
||||
goto exit;
|
||||
}
|
||||
link->hash_size = hash_size - 2;
|
||||
link->hash = (unsigned char*)malloc(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;
|
||||
struct NodeLink* temp_link = NULL;
|
||||
|
||||
if (buffer_length == 0)
|
||||
goto exit;
|
||||
|
||||
if (ipfs_hashtable_node_new(node) == 0)
|
||||
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)
|
||||
goto exit;
|
||||
pos += bytes_read;
|
||||
if (ipfs_node_link_protobuf_decode(temp_buffer, temp_size, &temp_link) == 0)
|
||||
goto exit;
|
||||
if (ipfs_node_link_protobuf_decode(temp_buffer, temp_size, &temp_link)) {
|
||||
ipfs_hashtable_node_add_link(*node, temp_link);
|
||||
}
|
||||
free(temp_buffer);
|
||||
temp_buffer = NULL;
|
||||
ipfs_hashtable_node_add_link(*node, temp_link);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../test_helper.h"
|
||||
#include "libp2p/utils/logger.h"
|
||||
#include "ipfs/cmd/cli.h"
|
||||
#include "ipfs/core/client_api.h"
|
||||
#include "ipfs/core/daemon.h"
|
||||
#include "ipfs/importer/exporter.h"
|
||||
|
@ -56,15 +57,15 @@ int test_core_api_object_cat() {
|
|||
int thread_started1 = 0;
|
||||
int thread_started2 = 0;
|
||||
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* config_file2 = "config.test2";
|
||||
char* config_file2 = "config.test2.wo_journal";
|
||||
struct FSRepo* fs_repo = NULL;
|
||||
char hash[256] = "";
|
||||
char* args[] = {"ipfs", "--config", ipfs_path2, "cat", hash };
|
||||
|
||||
// logging
|
||||
libp2p_logger_add_class("test_journal");
|
||||
libp2p_logger_add_class("test_api");
|
||||
libp2p_logger_add_class("journal");
|
||||
libp2p_logger_add_class("daemon");
|
||||
libp2p_logger_add_class("online");
|
||||
|
@ -82,6 +83,7 @@ int test_core_api_object_cat() {
|
|||
libp2p_logger_add_class("unixfs");
|
||||
libp2p_logger_add_class("bitswap_engine");
|
||||
libp2p_logger_add_class("bitswap_network");
|
||||
libp2p_logger_add_class("exporter");
|
||||
|
||||
// build 2 repos
|
||||
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);
|
||||
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";
|
||||
char* filename = "test1.txt";
|
||||
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);
|
||||
memset(hash, 0, 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_hashtable_node_free(node);
|
||||
|
||||
libp2p_logger_debug("test_api", "*** Firing up daemons ***\n");
|
||||
pthread_create(&daemon_thread1, NULL, test_daemon_start, (void*)ipfs_path1);
|
||||
thread_started1 = 1;
|
||||
sleep(3);
|
||||
pthread_create(&daemon_thread2, NULL, test_daemon_start, (void*)ipfs_path2);
|
||||
thread_started2 = 1;
|
||||
|
||||
sleep(3);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -133,6 +139,7 @@ int test_core_api_object_cat() {
|
|||
pthread_join(daemon_thread1, NULL);
|
||||
if (thread_started2)
|
||||
pthread_join(daemon_thread2, NULL);
|
||||
cli_arguments_free(arguments);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -249,12 +249,13 @@ int ipfs_unixfs_protobuf_encode(const struct UnixFS* incoming, unsigned char* ou
|
|||
* @param incoming the array of bytes
|
||||
* @param incoming_size the length of the array
|
||||
* @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) {
|
||||
// short cut for nulls
|
||||
if (incoming_size == 0) {
|
||||
*outgoing = NULL;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t pos = 0;
|
||||
|
|
Loading…
Reference in a new issue