| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 | program httpget;{$mode objfpc}{$h+}uses sysutils, ssockets, gnutls, uriparser;Const  logLevel = 0; // Set to positive value to enable logging.  // Correct this for your system.  DefaultCerts : PChar =  '/etc/ssl/certs/ca-certificates.crt';  MAX_BUF = 1024*256;  MSG = 'GET %s HTTP/1.0'#13#10'Host: %s'#13#10#13#10;Procedure MyLogFunc(level : longint; msg : PChar); cdecl;begin  writeln(StdErr,'Log[',Level:2,']: ',msg);end;Var  sock : TInetSocket;  ret : integer;  session : tgnutls_session_t;  buf : Array[0..MAX_BUF] of char;  cred : tgnutls_certificate_credentials_t;  errptr,desc : pchar;  FN, URL,S, HostName : String;  port : word;  uri : TURI;begin  if paramCount<1 then    begin    writeln('Usage : ',ExtractFileName(ParamStr(0)),' url');    Halt(1);    end;  url:=ParamStr(1);  uri:=ParseURI(URL,'https',443);  hostname:=uri.Host;  if uri.Protocol<>'https' then    begin    Writeln('Only https supported');    Halt(1);    end;  Port:=URI.Port;  FN:=uri.Path+URI.Document;  if (URI.Params<>'') then    FN:=FN+'?'+URI.Params;  if FN='' then FN:='/';  LoadGNutls();  gnutls_global_init();  ret := gnutls_certificate_allocate_credentials (@cred);  if (ret <> GNUTLS_E_SUCCESS) then    begin    writeln(stderr, 'error: gnutls_certificate_allocate_credentials: ', gnutls_strerror(ret));    halt(1);    end;  ret := gnutls_certificate_set_x509_trust_file(cred, defaultcerts, GNUTLS_X509_FMT_PEM);  if (ret = 0) then    begin    writeln(stderr, 'error: no certificates found in:', defaultcerts);    halt(1);    end  else if (ret < 0) then    begin    writeln(stderr, 'error: gnutls_certificate_set_x509_trust_files(',defaultcerts,'): ',	     gnutls_strerror(ret));    halt(1);    end;  if (logLevel>0) then    begin    gnutls_global_set_log_function(@MyLogFunc);    gnutls_global_set_log_level(logLevel);    end;  gnutls_init(@session, GNUTLS_CLIENT);  // We can also use  //  ret:=gnutls_set_default_priority(session);  ret := gnutls_priority_set_direct(session, 'NORMAL', @errptr);  if (ret <> GNUTLS_E_SUCCESS) then    begin    writeln(stderr, 'error: gnutls_priority_set_direct: ',gnutls_strerror(ret) , ' error: at: ', errptr);    halt(1);    end;  ret := gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred);  if (ret <> GNUTLS_E_SUCCESS) then    begin    writeln(stderr, 'error: gnutls_credentials_set: ', gnutls_strerror(ret));    halt(1);    end;  Sock:=TINetSocket.Create(HostName,Port);  gnutls_transport_set_int(session, Sock.Handle);  gnutls_handshake_set_timeout(session,GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);  ret := gnutls_server_name_set(session, GNUTLS_NAME_DNS,pchar(HostName), length(HostName));  if (ret <> GNUTLS_E_SUCCESS) then    begin    writeln(stderr, 'error: gnutls_server_name_set: ', gnutls_strerror(ret));    halt(1);    end;    gnutls_session_set_verify_cert(session,pchar(HostName),0);    Repeat    ret:=gnutls_handshake(session);    if Ret<>GNUTLS_E_SUCCESS then      Case ret of        GNUTLS_E_AGAIN : Writeln(StdErr,'Handshake again');        GNUTLS_E_INTERRUPTED : Writeln(StdErr,'Handshake interrupted');      else        Writeln(StdErr,'Error ',ret,' received, fatal : ',gnutls_error_is_fatal(ret));      end;  until (ret>=0)  or (gnutls_error_is_fatal(ret) <> 0);  if (ret < 0) then    begin    writeln(stderr, '*** Handshake failed');    gnutls_perror(ret);    end  else      begin    desc := gnutls_session_get_desc(session);    writeln(StdErr,'- Session info: ', desc);//    gnutls_free(desc);    end;  S:=Format(Msg,[FN,HostName]);  Writeln(StdErr,'Sending request : ',S);  gnutls_record_send(session, Pchar(S), length(S));  repeat    ret := gnutls_record_recv(session, @buf, MAX_BUF);    if (ret=0) then      writeln(StdErr,'- Peer has closed the TLS connection\n')    else if ((ret < 0) and (gnutls_error_is_fatal(ret) = 0)) then      writeln(stderr, '*** Warning: ', gnutls_strerror(ret))    else if (ret < 0) and (ret<>GNUTLS_E_PREMATURE_TERMINATION) then      Writeln(stderr, '*** Error: ', ret, ' : ',gnutls_strerror(ret))    else if (ret > 0) then        begin        writeln(StdErr,'- Received ',ret,' bytes: ');        SetLength(S,Ret);        Move(Buf[0],S[1],Ret);        Write(S);        end;  until (ret<=0) and Not ((ret=GNUTLS_E_INTERRUPTED) or (Ret=GNUTLS_E_AGAIN));  Writeln;  gnutls_bye(session, GNUTLS_SHUT_RDWR);  Sock.Free;  gnutls_deinit(session);  gnutls_certificate_free_credentials(cred);  gnutls_global_deinit();  FreeGnuTLS;end.
 |