1 /**
2 * Copyright (C) 2008 Happy Fish / YuQing
3 *
4 * FastDFS may be copied only under the terms of the GNU General
5 * Public License V3, which may be found in the FastDFS source kit.
6 * Please visit the FastDFS Home Page http://www.fastken.com/ for more detail.
7 **/
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include "fdfs_client.h"
17 #include "fdfs_global.h"
18 #include "fastcommon/base64.h"
19 #include "fastcommon/sockopt.h"
20 #include "fastcommon/logger.h"
21 #include "fdfs_http_shared.h"
22
writeToFileCallback(void * arg,const int64_t file_size,const char * data,const int current_size)23 int writeToFileCallback(void *arg, const int64_t file_size, const char *data, \
24 const int current_size)
25 {
26 if (arg == NULL)
27 {
28 return EINVAL;
29 }
30
31 if (fwrite(data, current_size, 1, (FILE *)arg) != 1)
32 {
33 return errno != 0 ? errno : EIO;
34 }
35
36 return 0;
37 }
38
uploadFileCallback(void * arg,const int64_t file_size,int sock)39 int uploadFileCallback(void *arg, const int64_t file_size, int sock)
40 {
41 int64_t total_send_bytes;
42 char *filename;
43
44 if (arg == NULL)
45 {
46 return EINVAL;
47 }
48
49 filename = (char *)arg;
50 return tcpsendfile(sock, filename, file_size, \
51 g_fdfs_network_timeout, &total_send_bytes);
52 }
53
main(int argc,char * argv[])54 int main(int argc, char *argv[])
55 {
56 char *conf_filename;
57 char *local_filename;
58 ConnectionInfo *pTrackerServer;
59 ConnectionInfo *pStorageServer;
60 int result;
61 ConnectionInfo storageServer;
62 char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
63 char remote_filename[256];
64 char master_filename[256];
65 FDFSMetaData meta_list[32];
66 int meta_count;
67 int i;
68 FDFSMetaData *pMetaList;
69 char token[32 + 1];
70 char file_id[128];
71 char file_url[256];
72 char szDatetime[20];
73 char szPortPart[16];
74 int url_len;
75 time_t ts;
76 char *file_buff;
77 int64_t file_size;
78 char *operation;
79 char *meta_buff;
80 int store_path_index;
81 FDFSFileInfo file_info;
82
83 printf("This is FastDFS client test program v%d.%02d\n" \
84 "\nCopyright (C) 2008, Happy Fish / YuQing\n" \
85 "\nFastDFS may be copied only under the terms of the GNU General\n" \
86 "Public License V3, which may be found in the FastDFS source kit.\n" \
87 "Please visit the FastDFS Home Page http://www.fastken.com/ \n" \
88 "for more detail.\n\n" \
89 , g_fdfs_version.major, g_fdfs_version.minor);
90
91 if (argc < 3)
92 {
93 printf("Usage: %s <config_file> <operation>\n" \
94 "\toperation: upload, download, getmeta, setmeta, " \
95 "delete and query_servers\n", argv[0]);
96 return 1;
97 }
98
99 log_init();
100 g_log_context.log_level = LOG_DEBUG;
101
102 conf_filename = argv[1];
103 operation = argv[2];
104 if ((result=fdfs_client_init(conf_filename)) != 0)
105 {
106 return result;
107 }
108
109 pTrackerServer = tracker_get_connection();
110 if (pTrackerServer == NULL)
111 {
112 fdfs_client_destroy();
113 return errno != 0 ? errno : ECONNREFUSED;
114 }
115
116 pStorageServer = NULL;
117 *group_name = '\0';
118 local_filename = NULL;
119 if (strcmp(operation, "upload") == 0)
120 {
121 int upload_type;
122 char *prefix_name;
123 const char *file_ext_name;
124 char slave_filename[256];
125 int slave_filename_len;
126
127 if (argc < 4)
128 {
129 printf("Usage: %s <config_file> upload " \
130 "<local_filename> [FILE | BUFF | CALLBACK] \n",\
131 argv[0]);
132 fdfs_client_destroy();
133 return EINVAL;
134 }
135
136 local_filename = argv[3];
137 if (argc == 4)
138 {
139 upload_type = FDFS_UPLOAD_BY_FILE;
140 }
141 else
142 {
143 if (strcmp(argv[4], "BUFF") == 0)
144 {
145 upload_type = FDFS_UPLOAD_BY_BUFF;
146 }
147 else if (strcmp(argv[4], "CALLBACK") == 0)
148 {
149 upload_type = FDFS_UPLOAD_BY_CALLBACK;
150 }
151 else
152 {
153 upload_type = FDFS_UPLOAD_BY_FILE;
154 }
155 }
156
157 store_path_index = 0;
158
159 {
160 ConnectionInfo storageServers[FDFS_MAX_SERVERS_EACH_GROUP];
161 ConnectionInfo *pServer;
162 ConnectionInfo *pServerEnd;
163 int storage_count;
164
165 if ((result=tracker_query_storage_store_list_without_group( \
166 pTrackerServer, storageServers, \
167 FDFS_MAX_SERVERS_EACH_GROUP, &storage_count, \
168 group_name, &store_path_index)) == 0)
169 {
170 printf("tracker_query_storage_store_list_without_group: \n");
171 pServerEnd = storageServers + storage_count;
172 for (pServer=storageServers; pServer<pServerEnd; pServer++)
173 {
174 printf("\tserver %d. group_name=%s, " \
175 "ip_addr=%s, port=%d\n", \
176 (int)(pServer - storageServers) + 1, \
177 group_name, pServer->ip_addr, pServer->port);
178 }
179 printf("\n");
180 }
181 }
182
183 if ((result=tracker_query_storage_store(pTrackerServer, \
184 &storageServer, group_name, &store_path_index)) != 0)
185 {
186 fdfs_client_destroy();
187 printf("tracker_query_storage fail, " \
188 "error no: %d, error info: %s\n", \
189 result, STRERROR(result));
190 return result;
191 }
192
193 printf("group_name=%s, ip_addr=%s, port=%d\n", \
194 group_name, storageServer.ip_addr, \
195 storageServer.port);
196
197 if ((pStorageServer=tracker_make_connection(&storageServer, \
198 &result)) == NULL)
199 {
200 fdfs_client_destroy();
201 return result;
202 }
203
204 memset(&meta_list, 0, sizeof(meta_list));
205 meta_count = 0;
206 strcpy(meta_list[meta_count].name, "ext_name");
207 strcpy(meta_list[meta_count].value, "jpg");
208 meta_count++;
209 strcpy(meta_list[meta_count].name, "width");
210 strcpy(meta_list[meta_count].value, "160");
211 meta_count++;
212 strcpy(meta_list[meta_count].name, "height");
213 strcpy(meta_list[meta_count].value, "80");
214 meta_count++;
215 strcpy(meta_list[meta_count].name, "file_size");
216 strcpy(meta_list[meta_count].value, "115120");
217 meta_count++;
218
219 file_ext_name = fdfs_get_file_ext_name(local_filename);
220 *group_name = '\0';
221
222 if (upload_type == FDFS_UPLOAD_BY_FILE)
223 {
224 result = storage_upload_by_filename(pTrackerServer, \
225 pStorageServer, store_path_index, \
226 local_filename, file_ext_name, \
227 meta_list, meta_count, \
228 group_name, remote_filename);
229
230 printf("storage_upload_by_filename\n");
231 }
232 else if (upload_type == FDFS_UPLOAD_BY_BUFF)
233 {
234 char *file_content;
235 if ((result=getFileContent(local_filename, \
236 &file_content, &file_size)) == 0)
237 {
238 result = storage_upload_by_filebuff(pTrackerServer, \
239 pStorageServer, store_path_index, \
240 file_content, file_size, file_ext_name, \
241 meta_list, meta_count, \
242 group_name, remote_filename);
243 free(file_content);
244 }
245
246 printf("storage_upload_by_filebuff\n");
247 }
248 else
249 {
250 struct stat stat_buf;
251
252 if (stat(local_filename, &stat_buf) == 0 && \
253 S_ISREG(stat_buf.st_mode))
254 {
255 file_size = stat_buf.st_size;
256 result = storage_upload_by_callback(pTrackerServer, \
257 pStorageServer, store_path_index, \
258 uploadFileCallback, local_filename, \
259 file_size, file_ext_name, \
260 meta_list, meta_count, \
261 group_name, remote_filename);
262 }
263
264 printf("storage_upload_by_callback\n");
265 }
266
267 if (result != 0)
268 {
269 printf("upload file fail, " \
270 "error no: %d, error info: %s\n", \
271 result, STRERROR(result));
272 tracker_close_connection_ex(pStorageServer, true);
273 fdfs_client_destroy();
274 return result;
275 }
276
277 if (g_tracker_server_http_port == 80)
278 {
279 *szPortPart = '\0';
280 }
281 else
282 {
283 sprintf(szPortPart, ":%d", g_tracker_server_http_port);
284 }
285
286 sprintf(file_id, "%s/%s", group_name, remote_filename);
287 url_len = sprintf(file_url, "http://%s%s/%s", \
288 pStorageServer->ip_addr, szPortPart, file_id);
289 if (g_anti_steal_token)
290 {
291 ts = time(NULL);
292 fdfs_http_gen_token(&g_anti_steal_secret_key, file_id, \
293 ts, token);
294 sprintf(file_url + url_len, "?token=%s&ts=%d", \
295 token, (int)ts);
296 }
297
298 printf("group_name=%s, remote_filename=%s\n", \
299 group_name, remote_filename);
300
301 fdfs_get_file_info(group_name, remote_filename, &file_info);
302 printf("source ip address: %s\n", file_info.source_ip_addr);
303 printf("file timestamp=%s\n", formatDatetime(
304 file_info.create_timestamp, "%Y-%m-%d %H:%M:%S", \
305 szDatetime, sizeof(szDatetime)));
306 printf("file size=%"PRId64"\n", file_info.file_size);
307 printf("file crc32=%u\n", file_info.crc32);
308 printf("example file url: %s\n", file_url);
309
310 strcpy(master_filename, remote_filename);
311 *remote_filename = '\0';
312 if (upload_type == FDFS_UPLOAD_BY_FILE)
313 {
314 prefix_name = "_big";
315 result = storage_upload_slave_by_filename(pTrackerServer,
316 NULL, local_filename, master_filename, \
317 prefix_name, file_ext_name, \
318 meta_list, meta_count, \
319 group_name, remote_filename);
320
321 printf("storage_upload_slave_by_filename\n");
322 }
323 else if (upload_type == FDFS_UPLOAD_BY_BUFF)
324 {
325 char *file_content;
326 prefix_name = "1024x1024";
327 if ((result=getFileContent(local_filename, \
328 &file_content, &file_size)) == 0)
329 {
330 result = storage_upload_slave_by_filebuff(pTrackerServer, \
331 NULL, file_content, file_size, master_filename,
332 prefix_name, file_ext_name, \
333 meta_list, meta_count, \
334 group_name, remote_filename);
335 free(file_content);
336 }
337
338 printf("storage_upload_slave_by_filebuff\n");
339 }
340 else
341 {
342 struct stat stat_buf;
343
344 prefix_name = "-small";
345 if (stat(local_filename, &stat_buf) == 0 && \
346 S_ISREG(stat_buf.st_mode))
347 {
348 file_size = stat_buf.st_size;
349 result = storage_upload_slave_by_callback(pTrackerServer, \
350 NULL, uploadFileCallback, local_filename, \
351 file_size, master_filename, prefix_name, \
352 file_ext_name, meta_list, meta_count, \
353 group_name, remote_filename);
354 }
355
356 printf("storage_upload_slave_by_callback\n");
357 }
358
359 if (result != 0)
360 {
361 printf("upload slave file fail, " \
362 "error no: %d, error info: %s\n", \
363 result, STRERROR(result));
364 tracker_close_connection_ex(pStorageServer, true);
365 fdfs_client_destroy();
366 return result;
367 }
368
369 if (g_tracker_server_http_port == 80)
370 {
371 *szPortPart = '\0';
372 }
373 else
374 {
375 sprintf(szPortPart, ":%d", g_tracker_server_http_port);
376 }
377
378 sprintf(file_id, "%s/%s", group_name, remote_filename);
379 url_len = sprintf(file_url, "http://%s%s/%s", \
380 pStorageServer->ip_addr, szPortPart, file_id);
381 if (g_anti_steal_token)
382 {
383 ts = time(NULL);
384 fdfs_http_gen_token(&g_anti_steal_secret_key, file_id, \
385 ts, token);
386 sprintf(file_url + url_len, "?token=%s&ts=%d", \
387 token, (int)ts);
388 }
389
390 printf("group_name=%s, remote_filename=%s\n", \
391 group_name, remote_filename);
392
393 fdfs_get_file_info(group_name, remote_filename, &file_info);
394
395 printf("source ip address: %s\n", file_info.source_ip_addr);
396 printf("file timestamp=%s\n", formatDatetime(
397 file_info.create_timestamp, "%Y-%m-%d %H:%M:%S", \
398 szDatetime, sizeof(szDatetime)));
399 printf("file size=%"PRId64"\n", file_info.file_size);
400 printf("file crc32=%u\n", file_info.crc32);
401 printf("example file url: %s\n", file_url);
402
403 if (fdfs_gen_slave_filename(master_filename, \
404 prefix_name, file_ext_name, \
405 slave_filename, &slave_filename_len) == 0)
406 {
407
408 if (strcmp(remote_filename, slave_filename) != 0)
409 {
410 printf("slave_filename=%s\n" \
411 "remote_filename=%s\n" \
412 "not equal!\n", \
413 slave_filename, remote_filename);
414 }
415 }
416 }
417 else if (strcmp(operation, "download") == 0 ||
418 strcmp(operation, "getmeta") == 0 ||
419 strcmp(operation, "setmeta") == 0 ||
420 strcmp(operation, "query_servers") == 0 ||
421 strcmp(operation, "delete") == 0)
422 {
423 if (argc < 5)
424 {
425 printf("Usage: %s <config_file> %s " \
426 "<group_name> <remote_filename>\n", \
427 argv[0], operation);
428 fdfs_client_destroy();
429 return EINVAL;
430 }
431
432 snprintf(group_name, sizeof(group_name), "%s", argv[3]);
433 snprintf(remote_filename, sizeof(remote_filename), \
434 "%s", argv[4]);
435 if (strcmp(operation, "setmeta") == 0 ||
436 strcmp(operation, "delete") == 0)
437 {
438 result = tracker_query_storage_update(pTrackerServer, \
439 &storageServer, group_name, remote_filename);
440 }
441 else if (strcmp(operation, "query_servers") == 0)
442 {
443 ConnectionInfo storageServers[FDFS_MAX_SERVERS_EACH_GROUP];
444 int server_count;
445
446 result = tracker_query_storage_list(pTrackerServer, \
447 storageServers, FDFS_MAX_SERVERS_EACH_GROUP, \
448 &server_count, group_name, remote_filename);
449
450 if (result != 0)
451 {
452 printf("tracker_query_storage_list fail, "\
453 "group_name=%s, filename=%s, " \
454 "error no: %d, error info: %s\n", \
455 group_name, remote_filename, \
456 result, STRERROR(result));
457 }
458 else
459 {
460 printf("server list (%d):\n", server_count);
461 for (i=0; i<server_count; i++)
462 {
463 printf("\t%s:%d\n", \
464 storageServers[i].ip_addr, \
465 storageServers[i].port);
466 }
467 printf("\n");
468 }
469
470 tracker_close_connection_ex(pTrackerServer, result != 0);
471 fdfs_client_destroy();
472 return result;
473 }
474 else
475 {
476 result = tracker_query_storage_fetch(pTrackerServer, \
477 &storageServer, group_name, remote_filename);
478 }
479
480 if (result != 0)
481 {
482 fdfs_client_destroy();
483 printf("tracker_query_storage_fetch fail, " \
484 "group_name=%s, filename=%s, " \
485 "error no: %d, error info: %s\n", \
486 group_name, remote_filename, \
487 result, STRERROR(result));
488 return result;
489 }
490
491 printf("storage=%s:%d\n", storageServer.ip_addr, \
492 storageServer.port);
493
494 if ((pStorageServer=tracker_make_connection(&storageServer, \
495 &result)) == NULL)
496 {
497 fdfs_client_destroy();
498 return result;
499 }
500
501 if (strcmp(operation, "download") == 0)
502 {
503 if (argc >= 6)
504 {
505 local_filename = argv[5];
506 if (strcmp(local_filename, "CALLBACK") == 0)
507 {
508 FILE *fp;
509 fp = fopen(local_filename, "wb");
510 if (fp == NULL)
511 {
512 result = errno != 0 ? errno : EPERM;
513 printf("open file \"%s\" fail, " \
514 "errno: %d, error info: %s", \
515 local_filename, result, \
516 STRERROR(result));
517 }
518 else
519 {
520 result = storage_download_file_ex( \
521 pTrackerServer, pStorageServer, \
522 group_name, remote_filename, 0, 0, \
523 writeToFileCallback, fp, &file_size);
524 fclose(fp);
525 }
526 }
527 else
528 {
529 result = storage_download_file_to_file( \
530 pTrackerServer, pStorageServer, \
531 group_name, remote_filename, \
532 local_filename, &file_size);
533 }
534 }
535 else
536 {
537 file_buff = NULL;
538 if ((result=storage_download_file_to_buff( \
539 pTrackerServer, pStorageServer, \
540 group_name, remote_filename, \
541 &file_buff, &file_size)) == 0)
542 {
543 local_filename = strrchr( \
544 remote_filename, '/');
545 if (local_filename != NULL)
546 {
547 local_filename++; //skip /
548 }
549 else
550 {
551 local_filename=remote_filename;
552 }
553
554 result = writeToFile(local_filename, \
555 file_buff, file_size);
556
557 free(file_buff);
558 }
559 }
560
561 if (result == 0)
562 {
563 printf("download file success, " \
564 "file size=%"PRId64", file save to %s\n", \
565 file_size, local_filename);
566 }
567 else
568 {
569 printf("download file fail, " \
570 "error no: %d, error info: %s\n", \
571 result, STRERROR(result));
572 }
573 }
574 else if (strcmp(operation, "getmeta") == 0)
575 {
576 if ((result=storage_get_metadata(pTrackerServer, \
577 pStorageServer, group_name, remote_filename, \
578 &pMetaList, &meta_count)) == 0)
579 {
580 printf("get meta data success, " \
581 "meta count=%d\n", meta_count);
582 for (i=0; i<meta_count; i++)
583 {
584 printf("%s=%s\n", \
585 pMetaList[i].name, \
586 pMetaList[i].value);
587 }
588
589 free(pMetaList);
590 }
591 else
592 {
593 printf("getmeta fail, " \
594 "error no: %d, error info: %s\n", \
595 result, STRERROR(result));
596 }
597 }
598 else if (strcmp(operation, "setmeta") == 0)
599 {
600 if (argc < 7)
601 {
602 printf("Usage: %s <config_file> %s " \
603 "<group_name> <remote_filename> " \
604 "<op_flag> <metadata_list>\n" \
605 "\top_flag: %c for overwrite, " \
606 "%c for merge\n" \
607 "\tmetadata_list: name1=value1," \
608 "name2=value2,...\n", \
609 argv[0], operation, \
610 STORAGE_SET_METADATA_FLAG_OVERWRITE, \
611 STORAGE_SET_METADATA_FLAG_MERGE);
612 fdfs_client_destroy();
613 return EINVAL;
614 }
615
616 meta_buff = strdup(argv[6]);
617 if (meta_buff == NULL)
618 {
619 printf("Out of memory!\n");
620 return ENOMEM;
621 }
622
623 pMetaList = fdfs_split_metadata_ex(meta_buff, \
624 ',', '=', &meta_count, &result);
625 if (pMetaList == NULL)
626 {
627 printf("Out of memory!\n");
628 free(meta_buff);
629 return ENOMEM;
630 }
631
632 if ((result=storage_set_metadata(pTrackerServer, \
633 NULL, group_name, remote_filename, \
634 pMetaList, meta_count, *argv[5])) == 0)
635 {
636 printf("set meta data success\n");
637 }
638 else
639 {
640 printf("setmeta fail, " \
641 "error no: %d, error info: %s\n", \
642 result, STRERROR(result));
643 }
644
645 free(meta_buff);
646 free(pMetaList);
647 }
648 else if(strcmp(operation, "delete") == 0)
649 {
650 if ((result=storage_delete_file(pTrackerServer, \
651 NULL, group_name, remote_filename)) == 0)
652 {
653 printf("delete file success\n");
654 }
655 else
656 {
657 printf("delete file fail, " \
658 "error no: %d, error info: %s\n", \
659 result, STRERROR(result));
660 }
661 }
662 }
663 else
664 {
665 fdfs_client_destroy();
666 printf("invalid operation: %s\n", operation);
667 return EINVAL;
668 }
669
670 /* for test only */
671 if ((result=fdfs_active_test(pTrackerServer)) != 0)
672 {
673 printf("active_test to tracker server %s:%d fail, errno: %d\n", \
674 pTrackerServer->ip_addr, pTrackerServer->port, result);
675 }
676
677 /* for test only */
678 if ((result=fdfs_active_test(pStorageServer)) != 0)
679 {
680 printf("active_test to storage server %s:%d fail, errno: %d\n", \
681 pStorageServer->ip_addr, pStorageServer->port, result);
682 }
683
684 tracker_close_connection_ex(pStorageServer, true);
685 tracker_close_connection_ex(pTrackerServer, true);
686
687 fdfs_client_destroy();
688
689 return result;
690 }
691
692