1 /***************************************************************************
2  begin       : Fri Feb 07 2003
3  copyright   : (C) 2021 by Martin Preuss
4  email       : martin@libchipcard.de
5 
6  ***************************************************************************
7  *                                                                         *
8  *   This library is free software; you can redistribute it and/or         *
9  *   modify it under the terms of the GNU Lesser General Public            *
10  *   License as published by the Free Software Foundation; either          *
11  *   version 2.1 of the License, or (at your option) any later version.    *
12  *                                                                         *
13  *   This library is distributed in the hope that it will be useful,       *
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
16  *   Lesser General Public License for more details.                       *
17  *                                                                         *
18  *   You should have received a copy of the GNU Lesser General Public      *
19  *   License along with this library; if not, write to the Free Software   *
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
21  *   MA  02111-1307  USA                                                   *
22  *                                                                         *
23  ***************************************************************************/
24 
25 /* included from gui.c */
26 
27 
28 
GWEN_Gui_ExtendSyncIo(const char * url,const char * defaultProto,int defaultPort,GWEN_SYNCIO * baseSio)29 GWEN_SYNCIO *GWEN_Gui_ExtendSyncIo(const char *url,
30                                    const char *defaultProto,
31                                    int defaultPort,
32                                    GWEN_SYNCIO *baseSio)
33 {
34   GWEN_GUI *gui;
35   GWEN_URL *u=NULL;
36   const char *sProtocol=NULL;
37   int port=0;
38   const char *addr=NULL;
39 
40   gui=GWEN_Gui_GetGui();
41   assert(gui);
42 
43   if (!(url && *url)) {
44     DBG_ERROR(GWEN_LOGDOMAIN, "Empty URL");
45     return NULL;
46   }
47 
48   if (url && *url) {
49     u=GWEN_Url_fromString(url);
50     if (u==NULL) {
51       DBG_ERROR(GWEN_LOGDOMAIN, "Invalid URL [%s]", url);
52       return NULL;
53     }
54 
55     /* determine protocol and port */
56     sProtocol=GWEN_Url_GetProtocol(u);
57     if (!(sProtocol && *sProtocol))
58       sProtocol=defaultProto;
59     port=GWEN_Url_GetPort(u);
60     if (port<1)
61       port=defaultPort;
62     addr=GWEN_Url_GetServer(u);
63     if (!(addr && *addr)) {
64       DBG_ERROR(GWEN_LOGDOMAIN, "Missing server in URL [%s]", url);
65       GWEN_Url_free(u);
66       return NULL;
67     }
68   }
69 
70   if (!(sProtocol && *sProtocol))
71     sProtocol="http";
72   if (port<1)
73     port=80;
74 
75   if (strcasecmp(sProtocol, "http")==0 ||
76       strcasecmp(sProtocol, "https")==0) {
77     GWEN_SYNCIO *sio;
78     GWEN_SYNCIO *baseLayer;
79     GWEN_DB_NODE *db;
80     GWEN_BUFFER *tbuf;
81     int rv;
82 
83     baseLayer=baseSio;
84 
85     if (strcasecmp(sProtocol, "https")==0) {
86       /* create TLS layer */
87       sio=GWEN_SyncIo_Tls_new(baseLayer);
88       if (sio==NULL) {
89         DBG_INFO(GWEN_LOGDOMAIN, "here");
90         GWEN_SyncIo_free(baseLayer);
91         GWEN_Url_free(u);
92         return NULL;
93       }
94       if (addr)
95         GWEN_SyncIo_Tls_SetRemoteHostName(sio, addr);
96       baseLayer=sio;
97     }
98 
99     /* create buffered layer as needed for HTTP */
100     sio=GWEN_SyncIo_Buffered_new(baseLayer);
101     if (sio==NULL) {
102       DBG_INFO(GWEN_LOGDOMAIN, "here");
103       GWEN_SyncIo_free(baseLayer);
104       GWEN_Url_free(u);
105       return NULL;
106     }
107     baseLayer=sio;
108 
109     /* create HTTP layer */
110     sio=GWEN_SyncIo_Http_new(baseLayer);
111     if (sio==NULL) {
112       DBG_INFO(GWEN_LOGDOMAIN, "here");
113       GWEN_SyncIo_free(baseLayer);
114       GWEN_Url_free(u);
115       return NULL;
116     }
117 
118     /* setup default command and header */
119     tbuf=GWEN_Buffer_new(0, 256, 0, 1);
120     db=GWEN_SyncIo_Http_GetDbCommandOut(sio);
121 
122     /* get command string (e.g. server-relative path plus variables) */
123     rv=GWEN_Url_toCommandString(u, tbuf);
124     if (rv<0) {
125       DBG_ERROR(GWEN_LOGDOMAIN, "Invalid path in URL, ignoring (%d)", rv);
126     }
127     else
128       GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "url", GWEN_Buffer_GetStart(tbuf));
129     GWEN_Buffer_free(tbuf);
130 
131     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "command", "GET");
132     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", "HTTP/1.0");
133 
134     /* preset some headers */
135     db=GWEN_SyncIo_Http_GetDbHeaderOut(sio);
136     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Host", addr);
137     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "close");
138 
139     /* done */
140     GWEN_Url_free(u);
141     return sio;
142   }
143   else {
144     /* just return raw base layer */
145     DBG_INFO(GWEN_LOGDOMAIN, "No special handling of protocol \"%s\", returning raw base layer.",
146              sProtocol?sProtocol:"(empty)");
147     return baseSio;
148   }
149 }
150 
151 
152 
GWEN_Gui_Internal_GetSyncIo(GWEN_UNUSED GWEN_GUI * gui,const char * url,const char * defaultProto,int defaultPort,GWEN_SYNCIO ** pSio)153 int GWENHYWFAR_CB GWEN_Gui_Internal_GetSyncIo(GWEN_UNUSED GWEN_GUI *gui,
154                                               const char *url,
155                                               const char *defaultProto,
156                                               int defaultPort,
157                                               GWEN_SYNCIO **pSio)
158 {
159   GWEN_URL *u;
160   const char *s;
161   int port;
162   const char *addr;
163   GWEN_SYNCIO *sio;
164   GWEN_SYNCIO *baseLayer;
165 
166   if (!(url && *url)) {
167     DBG_ERROR(GWEN_LOGDOMAIN, "Empty URL");
168     return GWEN_ERROR_INVALID;
169   }
170 
171   u=GWEN_Url_fromString(url);
172   if (u==NULL) {
173     DBG_ERROR(GWEN_LOGDOMAIN, "Invalid URL [%s]", url);
174     return GWEN_ERROR_INVALID;
175   }
176 
177   /* determine protocol and port */
178   s=GWEN_Url_GetProtocol(u);
179   if (!(s && *s))
180     s=defaultProto;
181   if (!(s && *s))
182     s="http";
183   port=GWEN_Url_GetPort(u);
184   if (port<1)
185     port=defaultPort;
186   if (port<1)
187     port=80;
188   addr=GWEN_Url_GetServer(u);
189   if (!(addr && *addr)) {
190     DBG_ERROR(GWEN_LOGDOMAIN, "Missing server in URL [%s]", url);
191     GWEN_Url_free(u);
192     return GWEN_ERROR_INVALID;
193   }
194 
195 
196   /* create base io */
197   sio=GWEN_SyncIo_Socket_new(GWEN_SocketTypeTCP, GWEN_AddressFamilyIP);
198   if (sio==NULL) {
199     DBG_INFO(GWEN_LOGDOMAIN, "here");
200     GWEN_Url_free(u);
201     return GWEN_ERROR_GENERIC;
202   }
203   GWEN_SyncIo_Socket_SetAddress(sio, addr);
204   GWEN_SyncIo_Socket_SetPort(sio, port);
205   baseLayer=sio;
206 
207   sio=GWEN_Gui_ExtendSyncIo(url, defaultProto, defaultPort, baseLayer);
208   if (sio==NULL) {
209     DBG_INFO(GWEN_LOGDOMAIN, "here");
210     GWEN_SyncIo_free(baseLayer);
211     GWEN_Url_free(u);
212     return GWEN_ERROR_GENERIC;
213   }
214 
215   /* done */
216   GWEN_Url_free(u);
217   *pSio=sio;
218   return 0;
219 }
220 
221 
222 
223 
224