@@ -350,38 +350,40 @@ static bool _endswith(const char *str, const char *suffix) {
350
350
return strcmp (str + (strlen (str ) - strlen (suffix )), suffix ) == 0 ;
351
351
}
352
352
353
- const char * ok_hosts [] = {"code.circuitpython.org" };
353
+ const char * ok_hosts [] = {
354
+ "code.circuitpython.org" ,
355
+ "127.0.0.1" ,
356
+ "localhost" ,
357
+ };
354
358
355
359
static bool _origin_ok (const char * origin ) {
356
360
const char * http = "http://" ;
357
361
const char * local = ".local" ;
358
362
359
- if (memcmp (origin , http , strlen (http )) != 0 ) {
363
+ // note: redirected requests send an Origin of "null" and will be caught by this
364
+ if (strncmp (origin , http , strlen (http )) != 0 ) {
360
365
return false;
361
366
}
362
367
// These are prefix checks up to : so that any port works.
363
368
const char * hostname = common_hal_mdns_server_get_hostname (& mdns );
364
369
const char * end = origin + strlen (http ) + strlen (hostname ) + strlen (local );
365
- if (memcmp (origin + strlen (http ), hostname , strlen (hostname )) == 0 &&
366
- memcmp (origin + strlen (http ) + strlen (hostname ), local , strlen (local )) == 0 &&
370
+ if (strncmp (origin + strlen (http ), hostname , strlen (hostname )) == 0 &&
371
+ strncmp (origin + strlen (http ) + strlen (hostname ), local , strlen (local )) == 0 &&
367
372
(end [0 ] == '\0' || end [0 ] == ':' )) {
368
373
return true;
369
374
}
370
375
371
376
end = origin + strlen (http ) + strlen (_our_ip_encoded );
372
- if (memcmp (origin + strlen (http ), _our_ip_encoded , strlen (_our_ip_encoded )) == 0 &&
377
+ if (strncmp (origin + strlen (http ), _our_ip_encoded , strlen (_our_ip_encoded )) == 0 &&
373
378
(end [0 ] == '\0' || end [0 ] == ':' )) {
374
379
return true;
375
380
}
376
381
377
- const char * localhost = "127.0.0.1:" ;
378
- if (memcmp (origin + strlen (http ), localhost , strlen (localhost )) == 0 ) {
379
- return true;
380
- }
381
-
382
382
for (size_t i = 0 ; i < MP_ARRAY_SIZE (ok_hosts ); i ++ ) {
383
- // This checks exactly.
384
- if (strcmp (origin + strlen (http ), ok_hosts [i ]) == 0 ) {
383
+ // Allows any port
384
+ end = origin + strlen (http ) + strlen (ok_hosts [i ]);
385
+ if (strncmp (origin + strlen (http ), ok_hosts [i ], strlen (ok_hosts [i ])) == 0
386
+ && (end [0 ] == '\0' || end [0 ] == ':' )) {
385
387
return true;
386
388
}
387
389
}
@@ -908,8 +910,11 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
908
910
} else if (strlen (request -> origin ) > 0 && !_origin_ok (request -> origin )) {
909
911
ESP_LOGE (TAG , "bad origin %s" , request -> origin );
910
912
_reply_forbidden (socket , request );
911
- } else if (memcmp (request -> path , "/fs/" , 4 ) == 0 ) {
912
- if (!request -> authenticated ) {
913
+ } else if (strncmp (request -> path , "/fs/" , 4 ) == 0 ) {
914
+ if (strcasecmp (request -> method , "OPTIONS" ) == 0 ) {
915
+ // OPTIONS is sent for CORS preflight, unauthenticated
916
+ _reply_access_control (socket , request );
917
+ } else if (!request -> authenticated ) {
913
918
if (_api_password [0 ] != '\0' ) {
914
919
_reply_unauthorized (socket , request );
915
920
} else {
@@ -930,9 +935,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
930
935
}
931
936
// Delete is almost identical for files and directories so share the
932
937
// implementation.
933
- if (strcmp (request -> method , "OPTIONS" ) == 0 ) {
934
- _reply_access_control (socket , request );
935
- } else if (strcmp (request -> method , "DELETE" ) == 0 ) {
938
+ if (strcasecmp (request -> method , "DELETE" ) == 0 ) {
936
939
if (_usb_active ()) {
937
940
_reply_conflict (socket , request );
938
941
return false;
@@ -962,7 +965,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
962
965
return true;
963
966
}
964
967
} else if (directory ) {
965
- if (strcmp (request -> method , "GET" ) == 0 ) {
968
+ if (strcasecmp (request -> method , "GET" ) == 0 ) {
966
969
FF_DIR dir ;
967
970
FRESULT res = f_opendir (fs , & dir , path );
968
971
// Put the / back for replies.
@@ -982,7 +985,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
982
985
}
983
986
984
987
f_closedir (& dir );
985
- } else if (strcmp(request -> method , "PUT" ) == 0 ) {
988
+ } else if (strcasecmp (request -> method , "PUT" ) == 0 ) {
986
989
if (_usb_active ()) {
987
990
_reply_conflict (socket , request );
988
991
return false;
@@ -1011,7 +1014,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
1011
1014
}
1012
1015
}
1013
1016
} else { // Dealing with a file.
1014
- if (strcmp (request -> method , "GET" ) == 0 ) {
1017
+ if (strcasecmp (request -> method , "GET" ) == 0 ) {
1015
1018
FIL active_file ;
1016
1019
FRESULT result = f_open (fs , & active_file , path , FA_READ );
1017
1020
@@ -1022,15 +1025,18 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
1022
1025
}
1023
1026
1024
1027
f_close (& active_file );
1025
- } else if (strcmp (request -> method , "PUT" ) == 0 ) {
1028
+ } else if (strcasecmp (request -> method , "PUT" ) == 0 ) {
1026
1029
_write_file_and_reply (socket , request , fs , path );
1027
1030
return true;
1028
1031
}
1029
1032
}
1030
1033
}
1031
- } else if (memcmp (request -> path , "/cp/" , 4 ) == 0 ) {
1034
+ } else if (strncmp (request -> path , "/cp/" , 4 ) == 0 ) {
1032
1035
const char * path = request -> path + 3 ;
1033
- if (strcmp (request -> method , "GET" ) != 0 ) {
1036
+ if (strcasecmp (request -> method , "OPTIONS" ) == 0 ) {
1037
+ // handle preflight requests to /cp/
1038
+ _reply_access_control (socket , request );
1039
+ } else if (strcasecmp (request -> method , "GET" ) != 0 ) {
1034
1040
_reply_method_not_allowed (socket , request );
1035
1041
} else if (strcmp (path , "/devices.json" ) == 0 ) {
1036
1042
_reply_with_devices_json (socket , request );
@@ -1051,7 +1057,7 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
1051
1057
} else {
1052
1058
_reply_missing (socket , request );
1053
1059
}
1054
- } else if (strcmp (request -> method , "GET" ) != 0 ) {
1060
+ } else if (strcasecmp (request -> method , "GET" ) != 0 ) {
1055
1061
_reply_method_not_allowed (socket , request );
1056
1062
} else {
1057
1063
if (strcmp (request -> path , "/" ) == 0 ) {
@@ -1168,27 +1174,27 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
1168
1174
request -> header_value [request -> offset - 1 ] = '\0' ;
1169
1175
request -> offset = 0 ;
1170
1176
request -> state = STATE_HEADER_KEY ;
1171
- if (strcmp (request -> header_key , "Authorization" ) == 0 ) {
1177
+ if (strcasecmp (request -> header_key , "Authorization" ) == 0 ) {
1172
1178
const char * prefix = "Basic " ;
1173
- request -> authenticated = memcmp (request -> header_value , prefix , strlen (prefix )) == 0 &&
1179
+ request -> authenticated = strncmp (request -> header_value , prefix , strlen (prefix )) == 0 &&
1174
1180
strcmp (_api_password , request -> header_value + strlen (prefix )) == 0 ;
1175
- } else if (strcmp (request -> header_key , "Host" ) == 0 ) {
1181
+ } else if (strcasecmp (request -> header_key , "Host" ) == 0 ) {
1176
1182
request -> redirect = strcmp (request -> header_value , "circuitpython.local" ) == 0 ;
1177
- } else if (strcmp (request -> header_key , "Content-Length" ) == 0 ) {
1183
+ } else if (strcasecmp (request -> header_key , "Content-Length" ) == 0 ) {
1178
1184
request -> content_length = strtoul (request -> header_value , NULL , 10 );
1179
- } else if (strcmp (request -> header_key , "Expect" ) == 0 ) {
1185
+ } else if (strcasecmp (request -> header_key , "Expect" ) == 0 ) {
1180
1186
request -> expect = strcmp (request -> header_value , "100-continue" ) == 0 ;
1181
- } else if (strcmp (request -> header_key , "Accept" ) == 0 ) {
1182
- request -> json = strcmp (request -> header_value , "application/json" ) == 0 ;
1183
- } else if (strcmp (request -> header_key , "Origin" ) == 0 ) {
1187
+ } else if (strcasecmp (request ->header_key , "Accept" ) == 0 ) {
1188
+ request -> json = strcasecmp (request -> header_value , "application/json" ) == 0 ;
1189
+ } else if (strcasecmp (request -> header_key , "Origin" ) == 0 ) {
1184
1190
strcpy (request -> origin , request -> header_value );
1185
- } else if (strcmp (request -> header_key , "X-Timestamp" ) == 0 ) {
1191
+ } else if (strcasecmp (request -> header_key , "X-Timestamp" ) == 0 ) {
1186
1192
request -> timestamp_ms = strtoull (request -> header_value , NULL , 10 );
1187
- } else if (strcmp (request -> header_key , "Upgrade" ) == 0 ) {
1193
+ } else if (strcasecmp (request -> header_key , "Upgrade" ) == 0 ) {
1188
1194
request -> websocket = strcmp (request -> header_value , "websocket" ) == 0 ;
1189
- } else if (strcmp (request -> header_key , "Sec-WebSocket-Version" ) == 0 ) {
1195
+ } else if (strcasecmp (request -> header_key , "Sec-WebSocket-Version" ) == 0 ) {
1190
1196
request -> websocket_version = strtoul (request -> header_value , NULL , 10 );
1191
- } else if (strcmp (request -> header_key , "Sec-WebSocket-Key" ) == 0 &&
1197
+ } else if (strcasecmp (request -> header_key , "Sec-WebSocket-Key" ) == 0 &&
1192
1198
strlen (request -> header_value ) == 24 ) {
1193
1199
strcpy (request -> websocket_key , request -> header_value );
1194
1200
}
0 commit comments