mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-20 05:37:57 +00:00
work towards making rhizome direct http pull work. #9
This commit is contained in:
parent
7c544b25f2
commit
a81dafa180
@ -511,3 +511,8 @@ extern unsigned char favicon_bytes[];
|
||||
extern int favicon_len;
|
||||
|
||||
int rhizome_import_from_files(const char *manifestpath,const char *filepath);
|
||||
int rhizome_fetch_request_manifest_by_prefix(struct sockaddr_in *peerip,
|
||||
unsigned char *prefix,
|
||||
int prefix_length,
|
||||
int importP);
|
||||
extern int rhizome_file_fetch_queue_count;
|
||||
|
@ -508,9 +508,9 @@ int rhizome_direct_parse_http_request(rhizome_http_request *r)
|
||||
r->request_length = 0;
|
||||
r->source_flags = 0;
|
||||
|
||||
/* Find the end of the headers and start of any body bytes that we have read so far.
|
||||
Copy the bytes to a separate buffer, because r->request and r->request_length get used
|
||||
internally in the parser.
|
||||
/* Find the end of the headers and start of any body bytes that we have read
|
||||
so far. Copy the bytes to a separate buffer, because r->request and
|
||||
r->request_length get used internally in the parser.
|
||||
*/
|
||||
if (contentlen) {
|
||||
char buffer[contentlen];
|
||||
@ -737,9 +737,24 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r)
|
||||
WARN("XXX Rhizome direct http pull yet implemented");
|
||||
/* Need to fetch manifest. Once we have the manifest, then we can
|
||||
use our normal bundle fetch routines from rhizome_fetch.c
|
||||
|
||||
Generate a request like: GET /rhizome/manifestbybar/<hex of bar>
|
||||
and add it to our list of HTTP fetch requests, then watch
|
||||
until the request is finished. That will give us the manifest.
|
||||
Then as noted above, we can use that to pull the file down using
|
||||
existing routines.
|
||||
*/
|
||||
if (!rhizome_fetch_request_manifest_by_prefix
|
||||
(&addr,(unsigned char *)&p[i+1],RHIZOME_BAR_PREFIX_BYTES,
|
||||
1 /* import, getting file if needed */))
|
||||
{
|
||||
/* Fetching the manifest, and then using it to see if we want to
|
||||
fetch the file for import is all handled asynchronously, so just
|
||||
wait for it to finish. */
|
||||
while(rhizome_file_fetch_queue_count) fd_poll();
|
||||
}
|
||||
|
||||
} else if (type==1&&r->pushP) {
|
||||
WARN("XXX rhizome direct http push not implemented");
|
||||
/* Form up the POST request to submit the appropriate bundle. */
|
||||
|
||||
/* Start by getting the manifest, which is the main thing we need, and also
|
||||
|
@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include <time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include "serval.h"
|
||||
#include "rhizome.h"
|
||||
|
||||
@ -782,9 +783,15 @@ void rhizome_write_content(rhizome_file_fetch_record *q, char *buffer, int bytes
|
||||
DEBUGF("Received all of file via rhizome -- now to import it");
|
||||
fclose(q->file);
|
||||
q->file = NULL;
|
||||
if (q->manifest) {
|
||||
rhizome_import_received_bundle(q->manifest);
|
||||
rhizome_manifest_free(q->manifest);
|
||||
q->manifest = NULL;
|
||||
} else {
|
||||
/* This was to fetch the manifest, so now fetch the file if needed */
|
||||
DEBUGF("Received a manifest in response to supplying a manifest prefix.");
|
||||
DEBUGF("XXX Not implemented scheduling the fetching of the file itself.");
|
||||
}
|
||||
rhizome_fetch_close(q);
|
||||
return;
|
||||
}
|
||||
@ -937,3 +944,91 @@ void rhizome_fetch_poll(struct sched_ent *alarm)
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int rhizome_fetch_request_manifest_by_prefix(struct sockaddr_in *peerip,
|
||||
unsigned char *prefix,
|
||||
int prefix_length,
|
||||
int importP)
|
||||
{
|
||||
assert(peerip);
|
||||
/* Transfer via HTTP over IPv4 */
|
||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sock == -1)
|
||||
return WHY_perror("socket");
|
||||
if (set_nonblock(sock) == -1) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
struct sockaddr_in addr = *peerip;
|
||||
addr.sin_family = AF_INET;
|
||||
INFOF("RHIZOME HTTP REQUEST, CONNECT family=%u port=%u addr=%u.%u.%u.%u",
|
||||
addr.sin_family, ntohs(addr.sin_port),
|
||||
((unsigned char*)&addr.sin_addr.s_addr)[0],
|
||||
((unsigned char*)&addr.sin_addr.s_addr)[1],
|
||||
((unsigned char*)&addr.sin_addr.s_addr)[2],
|
||||
((unsigned char*)&addr.sin_addr.s_addr)[3]
|
||||
);
|
||||
if (connect(sock, (struct sockaddr*)&addr, sizeof addr) == -1) {
|
||||
if (errno == EINPROGRESS) {
|
||||
if (debug & DEBUG_RHIZOME_RX)
|
||||
DEBUGF("connect() returned EINPROGRESS");
|
||||
} else {
|
||||
WHY_perror("connect");
|
||||
WHY("Failed to open socket to peer's rhizome web server");
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
rhizome_file_fetch_record *q=&file_fetch_queue[rhizome_file_fetch_queue_count];
|
||||
q->manifest = NULL;
|
||||
q->alarm.poll.fd=sock;
|
||||
bzero(q->fileid, sizeof(q->fileid));
|
||||
q->request_len = snprintf(q->request, sizeof q->request, "GET /rhizome/manifestbyprefix/%s HTTP/1.0\r\n\r\n", alloca_tohex(prefix,prefix_length));
|
||||
q->request_ofs=0;
|
||||
q->state=RHIZOME_FETCH_CONNECTING;
|
||||
q->file_len=-1;
|
||||
q->file_ofs=0;
|
||||
|
||||
/* XXX Don't forget to implement resume */
|
||||
/* XXX We should stream file straight into the database */
|
||||
const char *id = rhizome_manifest_get(q->manifest, "id", NULL, 0);
|
||||
if (id == NULL) {
|
||||
close(sock);
|
||||
return WHY("Manifest missing ID");
|
||||
}
|
||||
if (create_rhizome_import_dir() == -1)
|
||||
return -1;
|
||||
char filename[1024];
|
||||
if (!FORM_RHIZOME_IMPORT_PATH(filename, "file.%s", id)) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
q->manifest->dataFileName = strdup(filename);
|
||||
if ((q->file = fopen(q->manifest->dataFileName, "w")) == NULL) {
|
||||
WHY_perror("fopen");
|
||||
if (debug & DEBUG_RHIZOME_RX)
|
||||
DEBUGF("Could not open '%s' to write received file", q->manifest->dataFileName);
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
INFOF("RHIZOME HTTP REQUEST, GET \"/rhizome/file/%s\"", q->fileid);
|
||||
|
||||
/* Watch for activity on the socket */
|
||||
q->alarm.function=rhizome_fetch_poll;
|
||||
fetch_stats.name="rhizome_fetch_poll";
|
||||
q->alarm.stats=&fetch_stats;
|
||||
q->alarm.poll.events=POLLIN|POLLOUT;
|
||||
watch(&q->alarm);
|
||||
/* And schedule a timeout alarm */
|
||||
q->alarm.alarm=gettime_ms() + RHIZOME_IDLE_TIMEOUT;
|
||||
q->alarm.deadline = q->alarm.alarm + RHIZOME_IDLE_TIMEOUT;
|
||||
|
||||
schedule(&q->alarm);
|
||||
|
||||
rhizome_file_fetch_queue_count++;
|
||||
if (debug & DEBUG_RHIZOME_RX)
|
||||
DEBUGF("Queued file for fetching into %s (%d in queue)",
|
||||
q->manifest->dataFileName, rhizome_file_fetch_queue_count);
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#include "rhizome.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
Loading…
Reference in New Issue
Block a user