我想连接到没有gcm类的gcm服务(只有带openssl的本机套接字)。
ssl握手工作正常。但是当我将帖子请求发送到https时 服务器我得到了http 404错误。
如果我取消注释该行 " // strcat(FormBuffer1,"主机:gcm-http.googleapis.com \ r \ n");",服务器什么都不返回,连接似乎挂起。
我尝试了gcm-http.googleapis.com和android.googleapis.com。
是否有适用于GCM的https帖子示例?我发现只有使用gcm类的代码示例。
感谢您的回答!
我的C来源:
//gcc -lssl -lcrypto sock.c -o sock.o
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <stdlib.h>
#include <memory.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <stdarg.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
int main(int argc, char *argv[]){
int sd;
struct hostent *host;
struct sockaddr_in addr;
BIO *outbio = NULL;
SSL_METHOD *method;
SSL_CTX *ctx;
SSL *ssl;
char *req;
int req_len;
char hostname[] = "gcm-http.googleapis.com"; // https://gcm-http.googleapis.com/gcm/send
//char hostname[] = "www.gmx.de"; // https://gcm-http.googleapis.com/gcm/send
char certs[] = "/etc/ssl/certs/ca-certificates.crt";
int port = 443;
int bytes;
char buf[1];
char FormBuffer1[1024];
char FormBuffer2[1024];
int ContentLength;
char ContentLengthBuffer[10];
// added this to test
char dest_url[] = "https://gcm-http.googleapis.com/gcm/send";
BIO *certbio = NULL;
X509 *cert = NULL;
X509_NAME *certname = NULL;
BIO *outbio2 = NULL;
OpenSSL_add_all_algorithms();
ERR_load_BIO_strings();
ERR_load_crypto_strings();
SSL_load_error_strings();
outbio = BIO_new(BIO_s_file());
outbio = BIO_new_fp(stdout, BIO_NOCLOSE);
if(SSL_library_init() < 0){
BIO_printf(outbio, "Could not initialize the OpenSSL library !\n");
}
method = SSLv23_client_method();
ctx = SSL_CTX_new(method);
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
host = gethostbyname(hostname);
sd = socket(AF_INET, SOCK_STREAM, 0);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = *(long*)(host->h_addr);
if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) == -1 ) {
BIO_printf(outbio, "%s: Cannot connect to host %s [%s] on port %d.\n", argv[0], hostname, inet_ntoa(addr.sin_addr), port);
}
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sd);
SSL_connect(ssl);
// try something here
/* Get the remote certificate into the X509 structure */
printf("SSL_get_peer_certificate(ssl) \n");
cert = SSL_get_peer_certificate(ssl);
if (cert == NULL)
printf("Error: Could not get a certificate from: %s.\n", dest_url);
else
printf("Retrieved the server's certificate from: %s.\n", dest_url);
printf("\n");
/* extract various certificate information */
certname = X509_NAME_new();
certname = X509_get_subject_name(cert);
/* display the cert subject here */
BIO_printf(outbio, "Displaying the certificate subject data:\n");
X509_NAME_print_ex(outbio, certname, 0, 0);
BIO_printf(outbio, "\n\n");
/*
Format:
Content-Type:application/json
Authorization:key=....
{
"to" : ".......",
"data" : {
...
},
}*/
//req = "GET / HTTP/1.1\r\n Host: gcm-http.googleapis.com/gcm/send\r\n\r\n";
// header
strcpy(FormBuffer2, "{\"to\" : \"/topics/global\", \n \"data\": { \"message\" : \"Test123\", },\n }\n\r\n");
ContentLength = strlen(FormBuffer2);
sprintf(ContentLengthBuffer, "%d", ContentLength);
strcpy(FormBuffer1, "POST ");
strcat(FormBuffer1, "/gcm/send");
strcat(FormBuffer1, " HTTP/1.1\r\n");
//strcat(FormBuffer1, "Host: gcm-http.googleapis.com\r\n");
//strcat(FormBuffer1, "Host: android.googleapis.com\r\n ");
strcat(FormBuffer1, "Content-length: ");
strcat(FormBuffer1, ContentLengthBuffer);
strcat(FormBuffer1, "\r\nContent-Type:application/json\r\n");
strcat(FormBuffer1, "Authorization:key=AIzaSyA.....\r\n");
//strcat(FormBuffer, ContentLengthBuffer); // size of actual content
//strcat_s(FormBuffer, "\n\n");
req_len = strlen(FormBuffer1);
SSL_write(ssl, FormBuffer1, req_len);
req_len = strlen(FormBuffer2);
SSL_write(ssl, FormBuffer2, req_len);
memset(buf, '\0', sizeof(buf));
bytes = SSL_read(ssl, buf, sizeof(buf));
while(bytes > 0){
write(STDOUT_FILENO, buf, bytes);
memset(buf, '\0', sizeof(buf));
bytes = SSL_read(ssl, buf, sizeof(buf));
}
SSL_free(ssl);
close(sd);
SSL_CTX_free(ctx);
}
HTTP答案:
SSL_get_peer_certificate(ssl)
Retrieved the server's certificate from: https://gcm-http.googleapis.com/gcm/send.
Displaying the certificate subject data:
C=US, ST=California, L=Mountain View, O=Google Inc, CN=*.googleapis.com
HTTP/1.1 404 Not Found
Content-Type: text/html; charset=UTF-8
Content-Length: 1569
Date: Sat, 21 Nov 2015 20:26:47 GMT
Server: GFE/2.0
Connection: close
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
<title>Error 404 (Not Found)!!1</title>
<style>
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
</style>
<a href=//www.google.com/><span id=logo aria-label=Google></span></a>
<p><b>404.</b> <ins>That’s an error.</ins>
<p>The requested URL <code>/gcm/send</code> was not found on this server. <ins>That’s all we know.</ins>