Fossil SCM

Fix blob leaks in the http TH1 command. Also, reorganize it to prepare for future enhancements.

mistachkin 2013-10-18 05:03 tkt-change-hook
Commit 0db184fc8e750cde398862632628fd1ba1dfdd77
1 file changed +70 -52
+70 -52
--- src/th_main.c
+++ src/th_main.c
@@ -830,47 +830,46 @@
830830
re_free(pRe);
831831
return rc;
832832
}
833833
834834
/*
835
-** TH command: http -asynchronous url ?payload?
835
+** TH command: http ?-asynchronous? ?--? url ?payload?
836836
**
837837
** Perform an HTTP or HTTPS request for the specified URL. If a
838838
** payload is present, it will be interpreted as text/plain and
839839
** the POST method will be used; otherwise, the GET method will
840
-** be used. Currently, all requests must be asynchronous.
840
+** be used. Upon success, if the -asynchronous option is used, an
841
+** empty string is returned as the result; otherwise, the response
842
+** from the server is returned as the result. Synchronous requests
843
+** are not currently implemented.
841844
*/
845
+#define HTTP_WRONGNUMARGS "http ?-asynchronous? ?--? url ?payload?"
842846
static int httpCmd(
843847
Th_Interp *interp,
844848
void *p,
845849
int argc,
846850
const char **argv,
847851
int *argl
848852
){
849
- const char *zSep, *zType, *zRegexp, *zParams;
850
- Blob hdr, payload;
853
+ int nArg = 1;
854
+ int fAsynchronous = 0;
855
+ const char *zType, *zRegexp;
856
+ Blob payload;
851857
ReCompiled *pRe = 0;
852858
UrlData urlData;
853859
854
- if( argc<2 || fossil_strnicmp(argv[1], "-asynchronous", argl[1]) ){
855
- Th_ErrorMessage(interp,
856
- "synchronous http requests not yet implemented", 0, 0);
857
- return TH_ERROR;
858
- }
859
- --argc; ++argv; ++argl; /* advance to next argument */
860
- blob_zero(&payload);
861
- if( argc!=2 ){
862
- if( argc != 3 ){
863
- return Th_WrongNumArgs(interp, "http -asynchronous url ?payload?");
864
- }
865
- blob_append(&payload, argv[2], argl[2]);
866
- zType = "POST";
867
- }else{
868
- zType = "GET";
869
- }
870
- zParams = strrchr(argv[1], '?');
871
- url_parse_local(argv[1], 0, &urlData);
860
+ if( argc<2 || argc>5 ){
861
+ return Th_WrongNumArgs(interp, HTTP_WRONGNUMARGS);
862
+ }
863
+ if( fossil_strnicmp(argv[nArg], "-asynchronous", argl[nArg])==0 ){
864
+ fAsynchronous = 1; nArg++;
865
+ }
866
+ if( fossil_strcmp(argv[nArg], "--")==0 ) nArg++;
867
+ if( nArg+1!=argc && nArg+2!=argc ){
868
+ return Th_WrongNumArgs(interp, REGEXP_WRONGNUMARGS);
869
+ }
870
+ url_parse_local(argv[nArg], 0, &urlData);
872871
if( urlData.isSsh || urlData.isFile ){
873872
Th_ErrorMessage(interp, "url must be http:// or https://", 0, 0);
874873
return TH_ERROR;
875874
}
876875
zRegexp = db_get("th1-uri-regexp", 0);
@@ -885,42 +884,61 @@
885884
Th_SetResult(interp, "url not allowed", -1);
886885
re_free(pRe);
887886
return TH_ERROR;
888887
}
889888
re_free(pRe);
890
- if( transport_open(&urlData) ){
891
- Th_ErrorMessage(interp, transport_errmsg(&urlData), 0, 0);
889
+ blob_zero(&payload);
890
+ if( nArg+2==argc ){
891
+ blob_append(&payload, argv[nArg+1], argl[nArg+1]);
892
+ zType = "POST";
893
+ }else{
894
+ zType = "GET";
895
+ }
896
+ if( fAsynchronous ){
897
+ const char *zSep, *zParams;
898
+ Blob hdr;
899
+ zParams = strrchr(argv[nArg], '?');
900
+ if( strlen(urlData.path)>0 && zParams!=argv[nArg] ){
901
+ zSep = "";
902
+ }else{
903
+ zSep = "/";
904
+ }
905
+ blob_zero(&hdr);
906
+ blob_appendf(&hdr, "%s %s%s%s HTTP/1.0\r\n",
907
+ zType, zSep, urlData.path, zParams ? zParams : "");
908
+ if( urlData.proxyAuth ){
909
+ blob_appendf(&hdr, "Proxy-Authorization: %s\r\n", urlData.proxyAuth);
910
+ }
911
+ if( urlData.passwd && urlData.user && urlData.passwd[0]=='#' ){
912
+ char *zCredentials = mprintf("%s:%s", urlData.user, &urlData.passwd[1]);
913
+ char *zEncoded = encode64(zCredentials, -1);
914
+ blob_appendf(&hdr, "Authorization: Basic %s\r\n", zEncoded);
915
+ fossil_free(zEncoded);
916
+ fossil_free(zCredentials);
917
+ }
918
+ blob_appendf(&hdr, "Host: %s\r\n", urlData.hostname);
919
+ blob_appendf(&hdr, "User-Agent: Fossil/" RELEASE_VERSION
920
+ " (" MANIFEST_DATE " " MANIFEST_VERSION ")\r\n");
921
+ blob_appendf(&hdr, "Content-Type: text/plain\r\n");
922
+ blob_appendf(&hdr, "Content-Length: %d\r\n\r\n", blob_size(&payload));
923
+ if( transport_open(&urlData) ){
924
+ Th_ErrorMessage(interp, transport_errmsg(&urlData), 0, 0);
925
+ return TH_ERROR;
926
+ }
927
+ transport_send(&urlData, &hdr);
928
+ transport_send(&urlData, &payload);
929
+ blob_reset(&hdr);
930
+ blob_reset(&payload);
931
+ transport_close(&urlData);
932
+ Th_SetResult(interp, 0, 0); /* NOTE: Asynchronous, no results. */
933
+ return TH_OK;
934
+ }else{
935
+ blob_reset(&payload);
936
+ Th_ErrorMessage(interp,
937
+ "synchronous requests are not yet implemented", 0, 0);
892938
return TH_ERROR;
893939
}
894
- blob_zero(&hdr);
895
- if( strlen(urlData.path)>0 && zParams!=argv[1] ){
896
- zSep = "";
897
- }else{
898
- zSep = "/";
899
- }
900
- blob_appendf(&hdr, "%s %s%s%s HTTP/1.0\r\n",
901
- zType, zSep, urlData.path, zParams ? zParams : "");
902
- if( urlData.proxyAuth ){
903
- blob_appendf(&hdr, "Proxy-Authorization: %s\r\n", urlData.proxyAuth);
904
- }
905
- if( urlData.passwd && urlData.user && urlData.passwd[0]=='#' ){
906
- char *zCredentials = mprintf("%s:%s", urlData.user, &urlData.passwd[1]);
907
- char *zEncoded = encode64(zCredentials, -1);
908
- blob_appendf(&hdr, "Authorization: Basic %s\r\n", zEncoded);
909
- fossil_free(zEncoded);
910
- fossil_free(zCredentials);
911
- }
912
- blob_appendf(&hdr, "Host: %s\r\n", urlData.hostname);
913
- blob_appendf(&hdr, "User-Agent: Fossil/" RELEASE_VERSION
914
- " (" MANIFEST_DATE " " MANIFEST_VERSION ")\r\n");
915
- blob_appendf(&hdr, "Content-Type: text/plain\r\n");
916
- blob_appendf(&hdr, "Content-Length: %d\r\n\r\n", blob_size(&payload));
917
- transport_send(&urlData, &hdr);
918
- transport_send(&urlData, &payload);
919
- transport_close(&urlData);
920
- Th_SetResult(interp, 0, 0); /* NOTE: Asynchronous, no results yet. */
921
- return TH_OK;
922940
}
923941
924942
/*
925943
** Make sure the interpreter has been initialized. Initialize it if
926944
** it has not been already.
927945
--- src/th_main.c
+++ src/th_main.c
@@ -830,47 +830,46 @@
830 re_free(pRe);
831 return rc;
832 }
833
834 /*
835 ** TH command: http -asynchronous url ?payload?
836 **
837 ** Perform an HTTP or HTTPS request for the specified URL. If a
838 ** payload is present, it will be interpreted as text/plain and
839 ** the POST method will be used; otherwise, the GET method will
840 ** be used. Currently, all requests must be asynchronous.
 
 
 
841 */
 
842 static int httpCmd(
843 Th_Interp *interp,
844 void *p,
845 int argc,
846 const char **argv,
847 int *argl
848 ){
849 const char *zSep, *zType, *zRegexp, *zParams;
850 Blob hdr, payload;
 
 
851 ReCompiled *pRe = 0;
852 UrlData urlData;
853
854 if( argc<2 || fossil_strnicmp(argv[1], "-asynchronous", argl[1]) ){
855 Th_ErrorMessage(interp,
856 "synchronous http requests not yet implemented", 0, 0);
857 return TH_ERROR;
858 }
859 --argc; ++argv; ++argl; /* advance to next argument */
860 blob_zero(&payload);
861 if( argc!=2 ){
862 if( argc != 3 ){
863 return Th_WrongNumArgs(interp, "http -asynchronous url ?payload?");
864 }
865 blob_append(&payload, argv[2], argl[2]);
866 zType = "POST";
867 }else{
868 zType = "GET";
869 }
870 zParams = strrchr(argv[1], '?');
871 url_parse_local(argv[1], 0, &urlData);
872 if( urlData.isSsh || urlData.isFile ){
873 Th_ErrorMessage(interp, "url must be http:// or https://", 0, 0);
874 return TH_ERROR;
875 }
876 zRegexp = db_get("th1-uri-regexp", 0);
@@ -885,42 +884,61 @@
885 Th_SetResult(interp, "url not allowed", -1);
886 re_free(pRe);
887 return TH_ERROR;
888 }
889 re_free(pRe);
890 if( transport_open(&urlData) ){
891 Th_ErrorMessage(interp, transport_errmsg(&urlData), 0, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
892 return TH_ERROR;
893 }
894 blob_zero(&hdr);
895 if( strlen(urlData.path)>0 && zParams!=argv[1] ){
896 zSep = "";
897 }else{
898 zSep = "/";
899 }
900 blob_appendf(&hdr, "%s %s%s%s HTTP/1.0\r\n",
901 zType, zSep, urlData.path, zParams ? zParams : "");
902 if( urlData.proxyAuth ){
903 blob_appendf(&hdr, "Proxy-Authorization: %s\r\n", urlData.proxyAuth);
904 }
905 if( urlData.passwd && urlData.user && urlData.passwd[0]=='#' ){
906 char *zCredentials = mprintf("%s:%s", urlData.user, &urlData.passwd[1]);
907 char *zEncoded = encode64(zCredentials, -1);
908 blob_appendf(&hdr, "Authorization: Basic %s\r\n", zEncoded);
909 fossil_free(zEncoded);
910 fossil_free(zCredentials);
911 }
912 blob_appendf(&hdr, "Host: %s\r\n", urlData.hostname);
913 blob_appendf(&hdr, "User-Agent: Fossil/" RELEASE_VERSION
914 " (" MANIFEST_DATE " " MANIFEST_VERSION ")\r\n");
915 blob_appendf(&hdr, "Content-Type: text/plain\r\n");
916 blob_appendf(&hdr, "Content-Length: %d\r\n\r\n", blob_size(&payload));
917 transport_send(&urlData, &hdr);
918 transport_send(&urlData, &payload);
919 transport_close(&urlData);
920 Th_SetResult(interp, 0, 0); /* NOTE: Asynchronous, no results yet. */
921 return TH_OK;
922 }
923
924 /*
925 ** Make sure the interpreter has been initialized. Initialize it if
926 ** it has not been already.
927
--- src/th_main.c
+++ src/th_main.c
@@ -830,47 +830,46 @@
830 re_free(pRe);
831 return rc;
832 }
833
834 /*
835 ** TH command: http ?-asynchronous? ?--? url ?payload?
836 **
837 ** Perform an HTTP or HTTPS request for the specified URL. If a
838 ** payload is present, it will be interpreted as text/plain and
839 ** the POST method will be used; otherwise, the GET method will
840 ** be used. Upon success, if the -asynchronous option is used, an
841 ** empty string is returned as the result; otherwise, the response
842 ** from the server is returned as the result. Synchronous requests
843 ** are not currently implemented.
844 */
845 #define HTTP_WRONGNUMARGS "http ?-asynchronous? ?--? url ?payload?"
846 static int httpCmd(
847 Th_Interp *interp,
848 void *p,
849 int argc,
850 const char **argv,
851 int *argl
852 ){
853 int nArg = 1;
854 int fAsynchronous = 0;
855 const char *zType, *zRegexp;
856 Blob payload;
857 ReCompiled *pRe = 0;
858 UrlData urlData;
859
860 if( argc<2 || argc>5 ){
861 return Th_WrongNumArgs(interp, HTTP_WRONGNUMARGS);
862 }
863 if( fossil_strnicmp(argv[nArg], "-asynchronous", argl[nArg])==0 ){
864 fAsynchronous = 1; nArg++;
865 }
866 if( fossil_strcmp(argv[nArg], "--")==0 ) nArg++;
867 if( nArg+1!=argc && nArg+2!=argc ){
868 return Th_WrongNumArgs(interp, REGEXP_WRONGNUMARGS);
869 }
870 url_parse_local(argv[nArg], 0, &urlData);
 
 
 
 
 
 
 
871 if( urlData.isSsh || urlData.isFile ){
872 Th_ErrorMessage(interp, "url must be http:// or https://", 0, 0);
873 return TH_ERROR;
874 }
875 zRegexp = db_get("th1-uri-regexp", 0);
@@ -885,42 +884,61 @@
884 Th_SetResult(interp, "url not allowed", -1);
885 re_free(pRe);
886 return TH_ERROR;
887 }
888 re_free(pRe);
889 blob_zero(&payload);
890 if( nArg+2==argc ){
891 blob_append(&payload, argv[nArg+1], argl[nArg+1]);
892 zType = "POST";
893 }else{
894 zType = "GET";
895 }
896 if( fAsynchronous ){
897 const char *zSep, *zParams;
898 Blob hdr;
899 zParams = strrchr(argv[nArg], '?');
900 if( strlen(urlData.path)>0 && zParams!=argv[nArg] ){
901 zSep = "";
902 }else{
903 zSep = "/";
904 }
905 blob_zero(&hdr);
906 blob_appendf(&hdr, "%s %s%s%s HTTP/1.0\r\n",
907 zType, zSep, urlData.path, zParams ? zParams : "");
908 if( urlData.proxyAuth ){
909 blob_appendf(&hdr, "Proxy-Authorization: %s\r\n", urlData.proxyAuth);
910 }
911 if( urlData.passwd && urlData.user && urlData.passwd[0]=='#' ){
912 char *zCredentials = mprintf("%s:%s", urlData.user, &urlData.passwd[1]);
913 char *zEncoded = encode64(zCredentials, -1);
914 blob_appendf(&hdr, "Authorization: Basic %s\r\n", zEncoded);
915 fossil_free(zEncoded);
916 fossil_free(zCredentials);
917 }
918 blob_appendf(&hdr, "Host: %s\r\n", urlData.hostname);
919 blob_appendf(&hdr, "User-Agent: Fossil/" RELEASE_VERSION
920 " (" MANIFEST_DATE " " MANIFEST_VERSION ")\r\n");
921 blob_appendf(&hdr, "Content-Type: text/plain\r\n");
922 blob_appendf(&hdr, "Content-Length: %d\r\n\r\n", blob_size(&payload));
923 if( transport_open(&urlData) ){
924 Th_ErrorMessage(interp, transport_errmsg(&urlData), 0, 0);
925 return TH_ERROR;
926 }
927 transport_send(&urlData, &hdr);
928 transport_send(&urlData, &payload);
929 blob_reset(&hdr);
930 blob_reset(&payload);
931 transport_close(&urlData);
932 Th_SetResult(interp, 0, 0); /* NOTE: Asynchronous, no results. */
933 return TH_OK;
934 }else{
935 blob_reset(&payload);
936 Th_ErrorMessage(interp,
937 "synchronous requests are not yet implemented", 0, 0);
938 return TH_ERROR;
939 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
940 }
941
942 /*
943 ** Make sure the interpreter has been initialized. Initialize it if
944 ** it has not been already.
945

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button