2017-02-19 81 views
3

我做了一個C函數,通過https發送一個http請求,現在我需要抓住與該請求與Lua檢索到的圖像。 但是,當我刪除標題和保存身體圖像不是一個有效的。保存圖像從http響應與套接字在C和Lua

當文件請求的文本沒有錯誤發生。

這是發送HTTP請求

static char* receive(BIO *bio, int chunksize) { 
    int readbytes, count = 1; 
    char tmp[chunksize], *buf = NULL; 

    buf = (char *) malloc(chunksize * sizeof(char)); 
    buf[0] = '\0'; 
    while(1) { 
     readbytes = BIO_read(bio, tmp, chunksize - 1); 
     if(readbytes <= 0) break; 
     tmp[readbytes] = '\0'; 

     buf = (char *) realloc(buf, chunksize * sizeof(char) * count); 

     strncat(buf, tmp, strlen(tmp)); 

     count++; 
    } 
    return buf; 
} 

static int ssl_get(const char *host, const char *port, const char *request, char **response, const int datasize, const int hostsize) { 
    char host_port[hostsize]; 
    int host_size; 

    /* ssl */ 
    BIO *bio; 
    SSL *ssl; 
    SSL_CTX *ctx; 

    /* init ssl lib */ 
    SSL_library_init(); 
    ERR_load_BIO_strings(); 
    OpenSSL_add_all_algorithms(); 

    /* set up ssl context */ 
    ctx = SSL_CTX_new(SSLv23_client_method()); 

    /* set up connection */ 
    bio = BIO_new_ssl_connect(ctx); 
    BIO_get_ssl(bio, &ssl); 
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 

    /* create connection */ 
    /* host and port on the form of <host>:<port> */ 
    strncpy(host_port, host, strlen(host)); 
    host_size = strlen(host); 
    host_port[host_size] = ':'; 
    host_port[host_size + 1] = '\0'; 
    strncat(host_port, port, strlen(port)); 


    BIO_set_conn_hostname(bio, host_port); 

    if (BIO_do_connect(bio) <= 0) { 
     //fprintf(stderr, "Error attempting to connect\n"); 
     //ERR_print_errors_fp(stderr); 
     BIO_free_all(bio); 
     SSL_CTX_free(ctx); 
     return -2; 
    } 

    /* Send request */ 
    BIO_write(bio, request, strlen(request)); 

    /* read response */ 
    (*response) = receive(bio, datasize); 


    BIO_free_all(bio); 
    SSL_CTX_free(ctx); 

    return 0; 
} 

這是請求

GET host.org/path/to/image.png HTTP/1.0\r\n\r\n 

的功能,這是我所收到

HTTP/1.1 200 OK 
Server: nginx/1.10.2 
Date: Sun, 19 Feb 2017 20:41:58 GMT 
Content-Type: image/png 
Content-Length: 88746 
Last-Modified: Thu, 10 Nov 2016 00:30:48 GMT 
Connection: close 
ETag: "5823bfb8-15aaa" 
Strict-Transport-Security: max-age=15768000 
Accept-Ranges: bytes 

PNG 

Ü­¢ 
;«&_éÓöñ}®¸Ú6ËpkÕ²®ÚÃz·f­KÑÙfuY#¸ #åÂj½põ¿§Lá[ÉjùÝ5®çsã9ûIåå>%¸°Ôà`Pé§x×|QWqXá²!jØZOö­ºÿýõͺ¡Ws¦04ÜGM9¦¡FÄ¡¶|Ú*)˺9Émß6>8­ö»I#/jI®ÛfËþ.ã50Ï­ïð.éѦÚAíõX 

相反的第一部分隨瀏覽器下載圖片

PNG 

��� 
IHDR��U��m���Þ¡Z²���sRGB�®Îé���gAMA��±üa��� pHYs��Ä��Ä+���bKGD�ÿ�ÿ�ÿ ½§��ÿIDATx^ìüEÙÇ}­¼(Ò;IÐ;üCïI`�¥ªüc{[email protected]"*JUD 
"EPФ'[email protected]�é `Ë;ß¹Û¹½Ù½Ý»Ý»½»çûù<Éý÷övgggwç·Ï3Ï,´@£AAA¦x_ð¿ Ð"ª[email protected] B¨AAAhU - ¢JAA¡DT  ´*AAAQ% Ð^Q5ïj¡ªµg¨yÁ÷!óÔ#¾o¾r´Z¶äßO7NM>çÎôqýÛOuïlc\ý^ÒãôqÁ6¬y¶U6êÊdÁñ×ÅuFç{Û)ª­z 
uö_EÜ÷ÜãHs~Ò!¹\½Ò²Õ]/Ñç7®ÜyO{ÛM~×g§Îkñõ­>òì¹íÆ$·Î·ÝrU03øÛaæ5THôfº§ëaÔäàÏ>ÅÝød5¥íuáµ�®70|hðIènjëÅ_CmG®&éÁ¶ 8tëù+w¿µW©Z<î~­ÓÞ¢FTÍ;ã@åÓS.G¹jt?cZ°@Ûñú¯2ÑjÙü¿>n9E2]Õh*Íd¯ª*®î³ã¼9³OjâÜJyf/WK£¨¶^ü5Ô~Ês´ûvº 

所有代碼

Complete C library

Aux Lua module

的Lua腳本

#!/usr/bin/lua 

sslrequest = require "sslrequest" 
parse = require "parse" 

local protocol_, host, port, request = parse.spliturl("https://host.fake/path/to/image.png") 
local res = sslrequest.ssl_get(host, port, "GET " .. request .. " HTTP/1.0\r\n\r\n", 1024, 100) 
local _, body = separate_http(res) 

local f = assert(io.open("img.png", "wb")) 
f:write(body) 
f:close() 

我不知道我錯過了什麼

編輯: 以十六進制的圖像文件

圖像的瀏覽器下載

00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR 
00000010: 0000 0355 0000 026d 0806 0000 00de a15a ...U...m.......Z 
00000020: b200 0000 0173 5247 4200 aece 1ce9 0000 .....sRGB....... 
00000030: 0004 6741 4d41 0000 b18f 0bfc 6105 0000 ..gAMA......a... 
00000040: 0009 7048 5973 0000 0ec4 0000 0ec4 0195 ..pHYs.......... 
00000050: 2b0e 1b00 0000 0662 4b47 4400 ff00 ff00 +......bKGD..... 
00000060: ffa0 bda7 9300 00ff 8049 4441 5478 5eec .........IDATx^. 
00000070: 9d07 fc1c 45d9 c707 7dad bc28 20d2 3b49 ....E...}..(.;I 
00000080: 90d0 3bfc 43ef 4904 8260 00a5 aafc 637b ..;.C.I..`....c{ 
00000090: 4d40 9022 2a4a 5544 820d 120b 2022 4581 [email protected]"*JUD.... "E. 
000000a0: 5092 d0a4 2754 2140 6849 00e9 108a 2020 P...'[email protected] 
000000b0: 60cb 3bdf b99d dbb9 bdd9 bddd bbdd bbbd `.;............. 
000000c0: bbe7 fbf9 3cc9 fdf7 f676 6767 6777 e7b7 ....<....vgggw.. 
000000d0: cf33 cf2c b440 a304 4110 0441 1004 4110 .3.,[email protected] 
000000e0: 84a6 785f f0bf 2008 8220 0882 2008 82d0 ..x_.. .. .. ... 
000000f0: 0422 aa04 4110 0441 1004 4110 5a40 4495 ."[email protected] 
00000100: 2008 8220 0882 2008 420b 88a8 1204 4110 .. .. .B.....A. 
00000110: 0441 1004 4168 0111 5582 2008 8220 0882 .A..Ah..U. .. .. 
00000120: 2008 2d20 a24a 1004 4110 0441 1004 a105 .- .J..A..A.... 
00000130: 4454 0982 2008 8220 0882 20b4 8088 2a41 DT.. .. .. ...*A 
00000140: 1004 4110 0441 1084 1610 5125 0882 2008 ..A..A....Q%.. . 
00000150: 8220 0882 d002 5e51 35ef 8c11 6aa1 8516 . ....^Q5...j... 
00000160: aab5 1167 a879 c1f7 21f3 d419 2392 be6f ...g.y..!...#..o 
00000170: 17be 72b4 5ab6 e4df 4f1f 374e 4d0f 3ee7 ..r.Z...O.7NM.>. 
00000180: cef4 7195 fd1a 8bdb 4f1e 75ef 6c63 5cfd ..q.....O.u.lc\. 
00000190: 5ed2 1ee3 f471 c136 ac79 b655 36ea ca9c ^....q.6.y.U6... 
000001a0: 64c1 f184 d7c5 0875 46e7 1a7b db29 aaad d......uF..{.).. 
000001b0: 177a 0d75 80f6 5f07 45dc f7dc e348 737e .z.u.._.E....Hs~ 
000001c0: d296 21b9 5cbd d216 b2d5 5d2f d19b e737 ..!.\.....]/...7 
000001d0: aedc 791f 4f7b db4d 7ed7 67a7 ce6b f1f5 ..y.O{.M~.g..k.. 
000001e0: 95ad 3ef2 ec1b 14b9 edc6 241f b78f ceb7 ..>.......$..... 
000001f0: dd72 1111 5595 020f 9d30 33f8 db61 e604 .r..U....03..a.. 
00000200: 3554 1f48 17f4 970b 66ba 1aa7 eb61 d4e4 5T.H....f....a.. 
00000210: e0cf 0298 3ec5 ddf8 6435 a5ed 759e e118 ....>...d5..u... 
00000220: b500 8cae 3730 7c68 f049 e86e 8a6a ebc5 ....70|h.I.n.j.. 
00000230: 5f43 6d47 ae83 26e9 c1b6 2038 74eb f98d _CmG..&... 8t... 
00000240: 2b77 bfb5 57a9 875a 8a3c ee7e add3 dea2 +w..W..Z.<.~.... 
00000250: 4654 cd3b e340 e5d3 532e 9347 b96a 7488 FT.;[email protected] 
00000260: 1a3f 6381 5ab0 40db 8cf1 faaf 32d1 6ad9 [email protected] 
00000270: fcbf 9f3e 6e94 9639 4532 5dd5 682a cd64 ...>n..9E2].h*.d 
00000280: afaa 2aae eeb3 1ce3 bc39 b383 4f03 6ae2 ..*......9..O.j. 
00000290: dc4a 7966 8c2f 574b 109a a3a8 b65e fc35 .Jyf./WK.....^.5 
000002a0: d47e ca73 1db4 fb9e 9c76 7f9d ba9f 0aed .~.s.....v...... 
000002b0: a1b7 ce6f 5cb9 7bb7 bd66 3b7f bd7f ddb6 ...o\.{..f;..... 
000002c0: bf3d 97a3 4ed3 decf 8538 6a44 d5dc 87ad .=..N....8jD.... 
000002d0: a20a 3b06 159b ab26 0e04 5fe9 d31e f6f1 ..;....&.._..... 
000002e0: 7dae b88a da36 cb70 6bd5 84b2 859e aeda }....6.pk....... 
000002f0: 10c3 7ab7 66ad 4bd1 d966 7559 231a b809 ..z.f.K..fuY#... 
00000300: 23e5 c26a bd70 f5bf a74c e15b 84c9 6a94 #..j.p...L.[..j. 
00000310: f9dd 0835 c2ae e773 e339 fb49 e5e5 9b3e ...5...s.9.I...> 

圖像的程序下載

00000000: 8950 4e47 0d0a 1a0a 36cb 706b d584 b285 .PNG....6.pk.... 
00000010: 9eae da10 c37a b766 ad4b d1d9 6675 5923 .....z.f.K..fuY# 
00000020: 1ab8 0923 e5c2 6abd 70f5 bfa7 4ce1 5b84 ...#..j.p...L.[. 
00000030: c96a 94f9 dd08 35c2 aee7 73e3 39fb 49e5 .j....5...s.9.I. 
00000040: e59b 3e25 b8b0 06d4 e060 50e9 93a7 788e ..>%.....`P...x. 
00000050: d77f 7c51 5771 588f e1b2 9021 6ad8 5a95 ..|QWqX....!j.Z. 
00000060: 4ff6 adba ff18 fdf5 cdba a157 73a6 9a30 O..........Ws..0 
00000070: 34dc 474d 39a6 9fa1 46c4 94a1 b67c da12 4.GM9...F....|.. 
00000080: 2a29 cbba 8d18 39c9 6ddf 9136 3e38 adf6 *)....9.m..6>8.. 
00000090: bb49 2383 2f6a 49ae db90 66cb 1dfe 2ee3 .I#./jI...f..... 
000000a0: 3530 cfad ef8a 8df0 142e e91c d1a6 93da 50.............. 
000000b0: 41ed f51b 580a 773c c714 b7dd 52b6 9914 A...X.w<....R... 
000000c0: 75c9 3ee2 ae03 1f45 1c67 48c2 7dcf 732c u.>....E.gH.}.s, 
000000d0: 49e5 ac10 6977 75e7 b8c1 7db6 4a07 eea7 I...iwu...}.J... 
000000e0: 298f b7e6 7ce8 ef6a eb3d be7e d2ae 1747 )...|..j.=.~...G 
000000f0: d66b 2853 7b68 f87c 73b7 17bd 9784 e7dc .k(S{h.|s....... 
00000100: 6deb c9ed b633 cf4b df39 883f 2e4d caeb m....3.K.9.?.M.. 
00000110: d977 8f1a 17b3 bcba 8fa6 ae2f 1f8d aeb9 .w........./.... 
00000120: 90da e3d7 96a6 d2bc a43d 7f29 ea41 93a6 .........=.).A.. 
00000130: 5ccd dd07 d3d6 67dc 7d29 fe7e 55dd 8f59 \.....g.}).~U..Y 
00000140: 9ebe 3e7c 359e b5cc 456c bb76 3d6d a9da ..>|5...El.v=m.. 
00000150: 467c fd40 33c7 15ae af2d a90c 29ae cd86 F|[email protected])... 
00000160: 64dc 86ef 78c2 65d4 bf53 1fbe b2fb ee57 d...x.e..S.....W 
00000170: bad3 5865 daa0 5ac0 22dd ab5c 302d 5856 ..Xe..Z."..\0-XV 
00000180: 65ee c405 bacf 69be 1fd0 8a2b 58b8 4077 [email protected] 
00000190: 442b bf19 98a8 ff82 690b 0683 f5b2 59ed D+......i.....Y. 
000001a0: 3ec3 b2c4 d9c0 826a 31bc e5f0 2dab 90b4 >......j1...-... 
000001b0: eda4 63f3 ff6e 70c1 c489 03d5 cfd1 7a4b ..c..np.......zK 
000001c0: ac53 0fd5 f5d9 a7b7 ce2d fee3 9b5b 2d4b .S.......-...[-K 
000001d0: 9cb9 f516 ae6f b71f 778c beb2 fbd7 ad6c .....o..w......l 
000001e0: 3fb6 1cd5 b226 b593 e8fe b2ac db2c 4e7d ?....&.......,N} 
000001f0: 0efa b7d8 b86e f32d b7bf 7e5d ab3d 9790 .....n.-..~].=.. 
00000200: 58c6 c875 9074 8e26 26b4 83e4 7a48 3eae X..u.t.&&...zH>. 
00000210: a4f6 55b6 3693 b62e 93ae 031f f91d 6786 ..U.6.........g. 
00000220: fbde b441 671b 51ab 2d6b e376 d74c 19ea ...Ag.Q.-k.v.L.. 
00000230: 97c5 b585 5cee a719 8e37 b93d 63d1 73e9 ....\....7.=c.s. 
00000240: 1c4b ac25 972f db35 94ad 2d27 9d3f f739 .K.%./.5..-'.?.9 
00000250: 125f 97e1 fedc f593 db6d 9bcf 6fec 3918 ._.......m..o.9. 
00000260: 5830 505d 5ebb 8dd6 aee7 c105 8331 cbcd X0P]^........1.. 
00000270: 3e32 b437 1f49 e7ac 62f1 e7a8 f1ba 515a >2.7.I..b.....QZ 
00000280: bb3e 13eb 2143 b91a df07 5bbb cec2 edbb .>..!C....[..... 
00000290: ebb8 e573 cf4b b4cd a7af 0fb6 9d7c 3d63 ...s.K.......|=c 
000002a0: f1e5 847c b79d 77db 80ac e722 5b19 d25e ...|..w...."[..^ 
000002b0: 9bf1 e5cb b20d 883b 9efa fb87 bf1d 5508 .......;......U. 
000002c0: cf5b f85d 8da8 aa2f 54a3 9b81 efa0 b323 .[.].../T......# 
000002d0: f7a0 e396 3b05 f637 8cfa fdd6 9f30 5f39 ....;..7.....0_9 
000002e0: fc95 ef3f d914 83ca 7797 65f9 bdb3 ae5b ...?....w.e....[ 
000002f0: 58e7 c4d5 d79d 87ea fae1 4d20 6c14 d1ce X.........M l... 
00000300: 9abf 7c6e 23aa d9a7 dbe8 1a14 26ae 8e7c ..|n#.......&..| 
00000310: c495 2fb6 1c86 f80b 3cfc 9ddd 7796 755b ../.....<...w.u[ 

EDIT2: 這也發生在請求通過不安全的圖像HTTP與另一個客戶端(代碼如下)。第一個塊(直到PNG頭)很好,但如果我繼續做recv,我只會收到垃圾。

其他奇怪的是,不管緩衝區大小,第一個recv總是隻檢索PNG頭。

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 
#include <arpa/inet.h> 

#define MAXDATASIZE 100000 


void *get_in_addr(struct sockaddr *sa){ 
    if (sa->sa_family == AF_INET) { 
     return &(((struct sockaddr_in*)sa)->sin_addr); 
    } 

    return &(((struct sockaddr_in6*)sa)->sin6_addr); 
} 

int http_get(char *host, char *port, char *msg) { 
    int sockfd, numbytes; 
    char buf[MAXDATASIZE]; 
    struct addrinfo hints, *servinfo, *p; 
    int rv; 
    char s[INET6_ADDRSTRLEN]; 

    memset(&hints, 0, sizeof(hints)); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_STREAM; 

    if ((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) { 
     fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); 
     return 1; 
    } 

    for (p=servinfo; p!=NULL; p=p->ai_next){ 
     if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { 
      perror("client: socket"); 
      continue; 
     } 

     if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) { 
      close(sockfd); 
      perror("client: connect"); 
      continue; 
     } 

     break; 
    } 

    if (p == NULL) { 
     fprintf(stderr, "client: failed to connect\n"); 
     return 2; 
    } 

    // convert the IP to string 
    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof(s)); 
    printf("client: connecting to %s\n", s); 

    freeaddrinfo(servinfo); 

    // send 
    if (send(sockfd, msg, strlen(msg), 0) == -1) { 
     perror("send"); 
     exit(1); 
    } 

    // recv 
    if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) { 
     perror("recv"); 
     exit(1); 
    } 
    buf[numbytes] = '\0'; 

    printf("%s\n", buf); 
    printf("%d\n", numbytes); 

    close(sockfd); 

    return 0; 
} 

int main() { 
    http_get("host", "80", "GET /image.png HTTP/1.1\r\nHost: host:80\r\n\r\n"); 
} 
+0

我不嚴格地回答你的問題,但fot非常相同的用例我使用cURL包裝來獲取圖像並保存它。 –

+0

可能有效負載在http回答中被壓縮? –

+0

不知道我是否正確理解了你,但如果你刪除文件的標題信息,其餘部分將沒有意義。還有'malloc(chunksize * sizeof(char))',爲什麼不爲空終止字符保留額外的字節。 – macroland

回答

0

終於!

我之所以讓垃圾後的頭是因爲我使用功能NULL終止對圖像數據串(我想這就是爲什麼文本的反應是顯示就好了)。

而不是使用strncat函數的我做了一個使用固定大小來連接字符串串聯功能。

static char* concat(const char *dest, const char *src, size_t dest_size, size_t src_size) { 
    char *new = (char *) malloc(dest_size + src_size); 

    if (!dest && !src) return NULL; 

    if (!new) return NULL; 

    if (!dest) for (int i=0; i < src_size; i++) new[i] = src[i]; 
    else if (!src) for (int i=0; i < dest_size; i++) new[i] = dest[i]; 
    else { 
     for (int i=0; i< dest_size; i++) new[i] = dest[i]; 
     for (int i=dest_size, j=0; j < src_size ; i++, j++) new[i] = src[j]; 
    } 

    return new; 
} 

然後推不是NULL結尾的字符串到Lua堆棧我需要使用lua_pushlstring代替lua_pushstring,指定接收到的數據的總大小。

Here是完整的代碼。

謝謝! :)