mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
Update HTTP for WIN
This commit is contained in:
@@ -73,7 +73,6 @@ set(src
|
|||||||
src/tls12.c
|
src/tls12.c
|
||||||
src/tls13.c
|
src/tls13.c
|
||||||
src/file.c
|
src/file.c
|
||||||
src/http.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(tools
|
set(tools
|
||||||
@@ -222,13 +221,13 @@ if (ENABLE_GMT_0105_RNG)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
list(APPEND src src/rand_win.c)
|
list(APPEND src src/rand_win.c src/http_win.c)
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
list(APPEND src src/rand_apple.c)
|
list(APPEND src src/rand_apple.c src/http.c)
|
||||||
elseif (ANDROID)
|
elseif (ANDROID)
|
||||||
list(APPEND src src/rand.c)
|
list(APPEND src src/rand.c src/http.c)
|
||||||
else()
|
else()
|
||||||
list(APPEND src src/rand_unix.c)
|
list(APPEND src src/rand_unix.c src/http.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
207
src/http_win.c
Normal file
207
src/http_win.c
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <gmssl/socket.h>
|
||||||
|
#include <gmssl/http.h>
|
||||||
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
|
int http_parse_uri(const char *uri, char host[128], int *port, char path[256])
|
||||||
|
{
|
||||||
|
if (!uri || !host || !port || !path) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*host = 0;
|
||||||
|
*port = 80;
|
||||||
|
*path++ = '/';
|
||||||
|
*path = 0;
|
||||||
|
|
||||||
|
if (sscanf(uri, "http://%127[^:]:%i/%254[^\n]", host, port, path) == 3);
|
||||||
|
else if (sscanf(uri, "http://%127[^/]/%254[^\n]", host, path) == 2);
|
||||||
|
else if (sscanf(uri, "http://%127[^:]:%i[^/][^\n]", host, port) == 2);
|
||||||
|
else if (sscanf(uri, "http://%127[^/][^\n]", host) == 1);
|
||||||
|
else {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!host[0] || strchr(host, '/') || strchr(host, ':')) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*port <= 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int socket_recv_all(tls_socket_t sock, uint8_t *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
while (len) {
|
||||||
|
if ((n = tls_socket_recv(sock, buf, len, 0)) <= 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buf += n;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int http_parse_response(char *buf, size_t buflen, uint8_t **content, size_t *contentlen, size_t *left)
|
||||||
|
{
|
||||||
|
char *ok = "HTTP/1.1 200 OK\r\n";
|
||||||
|
char *p;
|
||||||
|
size_t headerlen;
|
||||||
|
|
||||||
|
if (buflen < strlen(ok) || memcmp(buf, ok, strlen(ok)) != 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (buf[buflen] != 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!(p = strstr(buf, "\r\n\r\n"))) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*content = (uint8_t *)(p + 4);
|
||||||
|
headerlen = *content - (uint8_t *)buf;
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
if (!(p = strstr(buf, "\r\nContent-Length: "))) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
p += strlen("\r\nContent-Length: ");
|
||||||
|
*contentlen = atoi(p);
|
||||||
|
if (*contentlen <= 0 || *contentlen > INT_MAX) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buflen -= headerlen;
|
||||||
|
if (buflen < *contentlen)
|
||||||
|
*left = *contentlen - buflen;
|
||||||
|
else *left = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define HTTP_GET_TEMPLATE "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "\r\n\r\n"
|
||||||
|
|
||||||
|
int http_get(const char *uri, uint8_t *buf, size_t *contentlen, size_t buflen)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char host[128];
|
||||||
|
int port;
|
||||||
|
char path[256];
|
||||||
|
struct hostent *hp;
|
||||||
|
struct sockaddr_in server;
|
||||||
|
tls_socket_t sock;
|
||||||
|
char get[sizeof(HTTP_GET_TEMPLATE) + sizeof(host) + sizeof(path)];
|
||||||
|
int getlen;
|
||||||
|
char response[1024];
|
||||||
|
uint8_t *p;
|
||||||
|
size_t len;
|
||||||
|
size_t left;
|
||||||
|
|
||||||
|
// WIN32
|
||||||
|
WORD wVersion;
|
||||||
|
WSADATA wsaData;
|
||||||
|
wVersion = MAKEWORD(2, 2);
|
||||||
|
int err;
|
||||||
|
sock_inited = 1;
|
||||||
|
|
||||||
|
// parse uri and compose request
|
||||||
|
if (http_parse_uri(uri, host, &port, path) != 1) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((getlen = snprintf(get, sizeof(get), HTTP_GET_TEMPLATE, path, host)) <= 0) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WIN32
|
||||||
|
if ((err = WSAStartup(wVersion, &wsaData)) != 0) {
|
||||||
|
fprintf(stderr, "WSAStartup error %d\n", err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect and send request
|
||||||
|
if (!(hp = gethostbyname(host))) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
server.sin_addr = *((struct in_addr *)hp->h_addr_list[0]);
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_port = htons(port);
|
||||||
|
|
||||||
|
int sock_inited = 0;
|
||||||
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
|
||||||
|
error_print();
|
||||||
|
fprintf(stderr, "%s: open socket error : %u\n", prog, WSAGetLastError());
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(sock, (struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR) {
|
||||||
|
error_print();
|
||||||
|
fprintf(stderr, "%s: connect error : %u\n", prog, WSAGetLastError());
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (tls_socket_send(sock, get, strlen(get), 0) != getlen) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if ((len = tls_socket_recv(sock, response, sizeof(response) - 1, 0)) <= 0) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
response[len] = 0;
|
||||||
|
|
||||||
|
// process response header and retrieve left
|
||||||
|
if (http_parse_response(response, len, &p, contentlen, &left) != 1) {
|
||||||
|
|
||||||
|
response[len] = 0;
|
||||||
|
fprintf(stderr, "Response:\n%s\n", response);
|
||||||
|
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (!buf || buflen < *contentlen) {
|
||||||
|
ret = 0;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
memcpy(buf, p, *contentlen - left);
|
||||||
|
if (left) {
|
||||||
|
if (socket_recv_all(sock, buf + *contentlen - left, left) != 1) {
|
||||||
|
error_print();
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (sock_inited) tls_socket_close(sock);
|
||||||
|
WSACleanup();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user