├── .gitignore ├── AndroidWebServer ├── build.xml ├── build │ ├── built-jar.properties │ └── classes │ │ ├── .netbeans_automatic_build │ │ ├── .netbeans_update_resources │ │ ├── androidhttpweb │ │ ├── Main.class │ │ ├── TinyWebServer$EchoThread.class │ │ └── TinyWebServer.class │ │ └── appapis │ │ └── queryfiles │ │ └── AppApis.class ├── dist │ ├── AndroidWebServer.jar │ └── README.TXT ├── manifest.mf ├── nbproject │ ├── build-impl.xml │ ├── genfiles.properties │ ├── project.properties │ └── project.xml └── src │ ├── androidhttpweb │ ├── Main.java │ └── TinyWebServer.java │ └── appapis │ └── queryfiles │ └── AppApis.java ├── LICENSE ├── README.md └── demo.png /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /AndroidWebServer/nbproject/private/ 3 | -------------------------------------------------------------------------------- /AndroidWebServer/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Builds, tests, and runs the project AndroidWebServer. 12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /AndroidWebServer/build/built-jar.properties: -------------------------------------------------------------------------------- 1 | #Fri, 10 Aug 2018 19:16:41 +0530 2 | 3 | 4 | /Users/cis/Desktop/mobile/android_web/Android-Web-Server/AndroidWebServer= 5 | -------------------------------------------------------------------------------- /AndroidWebServer/build/classes/.netbeans_automatic_build: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/AndroidWebServer/build/classes/.netbeans_automatic_build -------------------------------------------------------------------------------- /AndroidWebServer/build/classes/.netbeans_update_resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/AndroidWebServer/build/classes/.netbeans_update_resources -------------------------------------------------------------------------------- /AndroidWebServer/build/classes/androidhttpweb/Main.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/AndroidWebServer/build/classes/androidhttpweb/Main.class -------------------------------------------------------------------------------- /AndroidWebServer/build/classes/androidhttpweb/TinyWebServer$EchoThread.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/AndroidWebServer/build/classes/androidhttpweb/TinyWebServer$EchoThread.class -------------------------------------------------------------------------------- /AndroidWebServer/build/classes/androidhttpweb/TinyWebServer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/AndroidWebServer/build/classes/androidhttpweb/TinyWebServer.class -------------------------------------------------------------------------------- /AndroidWebServer/build/classes/appapis/queryfiles/AppApis.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/AndroidWebServer/build/classes/appapis/queryfiles/AppApis.class -------------------------------------------------------------------------------- /AndroidWebServer/dist/AndroidWebServer.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/AndroidWebServer/dist/AndroidWebServer.jar -------------------------------------------------------------------------------- /AndroidWebServer/dist/README.TXT: -------------------------------------------------------------------------------- 1 | ======================== 2 | BUILD OUTPUT DESCRIPTION 3 | ======================== 4 | 5 | When you build an Java application project that has a main class, the IDE 6 | automatically copies all of the JAR 7 | files on the projects classpath to your projects dist/lib folder. The IDE 8 | also adds each of the JAR files to the Class-Path element in the application 9 | JAR files manifest file (MANIFEST.MF). 10 | 11 | To run the project from the command line, go to the dist folder and 12 | type the following: 13 | 14 | java -jar "AndroidWebServer.jar" 15 | 16 | To distribute this project, zip up the dist folder (including the lib folder) 17 | and distribute the ZIP file. 18 | 19 | Notes: 20 | 21 | * If two JAR files on the project classpath have the same name, only the first 22 | JAR file is copied to the lib folder. 23 | * Only JAR files are copied to the lib folder. 24 | If the classpath contains other types of files or folders, these files (folders) 25 | are not copied. 26 | * If a library on the projects classpath also has a Class-Path element 27 | specified in the manifest,the content of the Class-Path element has to be on 28 | the projects runtime path. 29 | * To set a main class in a standard Java project, right-click the project node 30 | in the Projects window and choose Properties. Then click Run and enter the 31 | class name in the Main Class field. Alternatively, you can manually type the 32 | class name in the manifest Main-Class element. 33 | -------------------------------------------------------------------------------- /AndroidWebServer/manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /AndroidWebServer/nbproject/build-impl.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | Must set src.dir 234 | Must set test.src.dir 235 | Must set build.dir 236 | Must set dist.dir 237 | Must set build.classes.dir 238 | Must set dist.javadoc.dir 239 | Must set build.test.classes.dir 240 | Must set build.test.results.dir 241 | Must set build.classes.excludes 242 | Must set dist.jar 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | Must set javac.includes 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | No tests executed. 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | Must set JVM to use for profiling in profiler.info.jvm 723 | Must set profiler agent JVM arguments in profiler.info.jvmargs.agent 724 | 725 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | Must select some files in the IDE or set javac.includes 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | To run this application from the command line without Ant, try: 1002 | 1003 | java -jar "${dist.jar.resolved}" 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | Must select one file in the IDE or set run.class 1051 | 1052 | 1053 | 1054 | Must select one file in the IDE or set run.class 1055 | 1056 | 1057 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | Must select one file in the IDE or set debug.class 1082 | 1083 | 1084 | 1085 | 1086 | Must select one file in the IDE or set debug.class 1087 | 1088 | 1089 | 1090 | 1091 | Must set fix.includes 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1103 | 1106 | 1107 | This target only works when run from inside the NetBeans IDE. 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | Must select one file in the IDE or set profile.class 1117 | This target only works when run from inside the NetBeans IDE. 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | This target only works when run from inside the NetBeans IDE. 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | This target only works when run from inside the NetBeans IDE. 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | Must select one file in the IDE or set run.class 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | Must select some files in the IDE or set test.includes 1184 | 1185 | 1186 | 1187 | 1188 | Must select one file in the IDE or set run.class 1189 | 1190 | 1191 | 1192 | 1193 | Must select one file in the IDE or set applet.url 1194 | 1195 | 1196 | 1197 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | Must select some files in the IDE or set javac.includes 1273 | 1274 | 1275 | 1276 | 1277 | 1278 | 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | 1289 | 1290 | 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | Some tests failed; see details above. 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | 1304 | 1305 | Must select some files in the IDE or set test.includes 1306 | 1307 | 1308 | 1309 | Some tests failed; see details above. 1310 | 1311 | 1312 | 1313 | Must select some files in the IDE or set test.class 1314 | Must select some method in the IDE or set test.method 1315 | 1316 | 1317 | 1318 | Some tests failed; see details above. 1319 | 1320 | 1321 | 1326 | 1327 | Must select one file in the IDE or set test.class 1328 | 1329 | 1330 | 1331 | Must select one file in the IDE or set test.class 1332 | Must select some method in the IDE or set test.method 1333 | 1334 | 1335 | 1336 | 1337 | 1338 | 1339 | 1340 | 1341 | 1342 | 1343 | 1344 | 1349 | 1350 | Must select one file in the IDE or set applet.url 1351 | 1352 | 1353 | 1354 | 1355 | 1356 | 1357 | 1362 | 1363 | Must select one file in the IDE or set applet.url 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | 1376 | 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 1394 | 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | 1405 | 1406 | 1407 | 1408 | 1409 | 1410 | 1411 | 1412 | 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | 1421 | -------------------------------------------------------------------------------- /AndroidWebServer/nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=b6a2e26a 2 | build.xml.script.CRC32=e336372b 3 | build.xml.stylesheet.CRC32=8064a381@1.80.1.48 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=b6a2e26a 7 | nbproject/build-impl.xml.script.CRC32=7af44df6 8 | nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48 9 | -------------------------------------------------------------------------------- /AndroidWebServer/nbproject/project.properties: -------------------------------------------------------------------------------- 1 | annotation.processing.enabled=true 2 | annotation.processing.enabled.in.editor=false 3 | annotation.processing.processors.list= 4 | annotation.processing.run.all.processors=true 5 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output 6 | application.title=AndroidWebServer 7 | application.vendor=cis 8 | auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml 9 | build.classes.dir=${build.dir}/classes 10 | build.classes.excludes=**/*.java,**/*.form 11 | # This directory is removed when the project is cleaned: 12 | build.dir=build 13 | build.generated.dir=${build.dir}/generated 14 | build.generated.sources.dir=${build.dir}/generated-sources 15 | # Only compile against the classpath explicitly listed here: 16 | build.sysclasspath=ignore 17 | build.test.classes.dir=${build.dir}/test/classes 18 | build.test.results.dir=${build.dir}/test/results 19 | # Uncomment to specify the preferred debugger connection transport: 20 | #debug.transport=dt_socket 21 | debug.classpath=\ 22 | ${run.classpath} 23 | debug.test.classpath=\ 24 | ${run.test.classpath} 25 | # Files in build.classes.dir which should be excluded from distribution jar 26 | dist.archive.excludes= 27 | # This directory is removed when the project is cleaned: 28 | dist.dir=dist 29 | dist.jar=${dist.dir}/AndroidWebServer.jar 30 | dist.javadoc.dir=${dist.dir}/javadoc 31 | endorsed.classpath= 32 | excludes= 33 | includes=** 34 | jar.archive.disabled=${jnlp.enabled} 35 | jar.compress=false 36 | jar.index=${jnlp.enabled} 37 | javac.classpath= 38 | # Space-separated list of extra javac options 39 | javac.compilerargs= 40 | javac.deprecation=false 41 | javac.external.vm=true 42 | javac.processorpath=\ 43 | ${javac.classpath} 44 | javac.source=1.8 45 | javac.target=1.8 46 | javac.test.classpath=\ 47 | ${javac.classpath}:\ 48 | ${build.classes.dir} 49 | javac.test.processorpath=\ 50 | ${javac.test.classpath} 51 | javadoc.additionalparam= 52 | javadoc.author=true 53 | javadoc.encoding=${source.encoding} 54 | javadoc.noindex=false 55 | javadoc.nonavbar=false 56 | javadoc.notree=false 57 | javadoc.private=false 58 | javadoc.splitindex=true 59 | javadoc.use=true 60 | javadoc.version=true 61 | javadoc.windowtitle= 62 | jnlp.codebase.type=no.codebase 63 | jnlp.descriptor=application 64 | jnlp.enabled=false 65 | jnlp.mixed.code=default 66 | jnlp.offline-allowed=false 67 | jnlp.signed=false 68 | jnlp.signing= 69 | jnlp.signing.alias= 70 | jnlp.signing.keystore= 71 | main.class= 72 | # Optional override of default Application-Library-Allowable-Codebase attribute identifying the locations where your signed RIA is expected to be found. 73 | manifest.custom.application.library.allowable.codebase= 74 | # Optional override of default Caller-Allowable-Codebase attribute identifying the domains from which JavaScript code can make calls to your RIA without security prompts. 75 | manifest.custom.caller.allowable.codebase= 76 | # Optional override of default Codebase manifest attribute, use to prevent RIAs from being repurposed 77 | manifest.custom.codebase= 78 | # Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions) 79 | manifest.custom.permissions= 80 | manifest.file=manifest.mf 81 | meta.inf.dir=${src.dir}/META-INF 82 | mkdist.disabled=false 83 | platform.active=default_platform 84 | project.license=mit 85 | run.classpath=\ 86 | ${javac.classpath}:\ 87 | ${build.classes.dir} 88 | # Space-separated list of JVM arguments used when running the project. 89 | # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. 90 | # To set system properties for unit tests define test-sys-prop.name=value: 91 | run.jvmargs= 92 | run.test.classpath=\ 93 | ${javac.test.classpath}:\ 94 | ${build.test.classes.dir} 95 | source.encoding=UTF-8 96 | src.dir=src 97 | test.src.dir=test 98 | -------------------------------------------------------------------------------- /AndroidWebServer/nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | AndroidWebServer 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /AndroidWebServer/src/androidhttpweb/Main.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2018 Sonu Auti | sonuauti.com | twitter -> @sonuauti 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package androidhttpweb; 25 | 26 | /** 27 | * 28 | * @author Sonu Auti 29 | */ 30 | public class Main { 31 | 32 | public Main(){ 33 | //call contructor with local ip, port , public html files path 34 | TinyWebServer.startServer("localhost",9000, "/Users/cis/Desktop/web/public_html"); 35 | 36 | } 37 | 38 | //use for testing 39 | public static void main(String[] args) { 40 | try { 41 | new Main(); 42 | } catch (Exception e) { 43 | e.printStackTrace(); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /AndroidWebServer/src/androidhttpweb/TinyWebServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2018 Sonu Auti http://sonuauti.com twitter @SonuAuti 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package androidhttpweb; 25 | 26 | import java.io.BufferedWriter; 27 | import java.io.DataInputStream; 28 | import java.io.DataOutputStream; 29 | import java.io.File; 30 | import java.io.FileInputStream; 31 | import java.io.IOException; 32 | import java.io.OutputStreamWriter; 33 | import java.io.PrintWriter; 34 | import java.lang.reflect.Method; 35 | import java.net.InetAddress; 36 | import java.net.ServerSocket; 37 | import java.net.Socket; 38 | import java.net.SocketTimeoutException; 39 | import java.net.URL; 40 | import java.net.URLDecoder; 41 | import java.text.SimpleDateFormat; 42 | import java.util.Date; 43 | import java.util.HashMap; 44 | import java.util.Hashtable; 45 | import java.util.Locale; 46 | import java.util.Map; 47 | import java.util.TimeZone; 48 | import java.util.regex.Pattern; 49 | 50 | /** 51 | * 52 | * @author Sonu Auti @cis 53 | */ 54 | public class TinyWebServer extends Thread { 55 | 56 | /** 57 | * @param args the command line arguments 58 | */ 59 | private static ServerSocket serverSocket; 60 | private final Map lowerCaseHeader = new HashMap<>(); 61 | 62 | public static String CONTENT_TYPE = "text/html"; 63 | private String CONTENT_DATE = ""; 64 | private String CONN_TYPE = ""; 65 | private String Content_Encoding = ""; 66 | private String content_length = ""; 67 | private String STATUS = "200"; 68 | private boolean keepAlive = true; 69 | private String SERVER_NAME = "Firefly http server v0.1"; 70 | private static final String MULTIPART_FORM_DATA_HEADER = "multipart/form-data"; 71 | private static final String ASCII_ENCODING = "US-ASCII"; 72 | private String REQUEST_TYPE = "GET"; 73 | private String HTTP_VER = "HTTP/1.1"; 74 | 75 | //all status 76 | public static String PAGE_NOT_FOUND = "404"; 77 | public static String OKAY = "200"; 78 | public static String CREATED = "201"; 79 | public static String ACCEPTED = "202"; 80 | public static String NO_CONTENT = "204"; 81 | public static String PARTIAL_NO_CONTENT = "206"; 82 | public static String MULTI_STATUS = "207"; 83 | public static String MOVED_PERMANENTLY = "301"; 84 | public static String SEE_OTHER = "303"; 85 | public static String NOT_MODIFIED = "304"; 86 | public static String TEMP_REDIRECT = "307"; 87 | public static String BAD_REQUEST = "400"; 88 | public static String UNAUTHORIZED_REQUEST = "401"; 89 | public static String FORBIDDEN = "403"; 90 | public static String NOT_FOUND = "404"; 91 | public static String METHOD_NOT_ALLOWED = "405"; 92 | public static String NOT_ACCEPTABLE = "406"; 93 | public static String REQUEST_TIMEOUT = "408"; 94 | public static String CONFLICT = "409"; 95 | public static String GONE = "410"; 96 | public static String LENGTH_REQUIRED = "411"; 97 | public static String PRECONDITION_FAILED = "412"; 98 | 99 | public static String PAYLOAD_TOO_LARGE = "413"; 100 | public static String UNSUPPORTED_MEDIA_TYPE = "415"; 101 | public static String RANGE_NOT_SATISFIABLE = "416"; 102 | public static String EXPECTATION_FAILED = "417"; 103 | public static String TOO_MANY_REQUESTS = "429"; 104 | 105 | public static String INTERNAL_ERROR = "500"; 106 | public static String NOT_IMPLEMENTED = "501"; 107 | public static String SERVICE_UNAVAILABLE = "503"; 108 | public static String UNSUPPORTED_HTTP_VERSION = "505"; 109 | 110 | public static final String CONTENT_DISPOSITION_REGEX = "([ |\t]*Content-Disposition[ |\t]*:)(.*)"; 111 | 112 | public static final Pattern CONTENT_DISPOSITION_PATTERN = Pattern.compile(CONTENT_DISPOSITION_REGEX, Pattern.CASE_INSENSITIVE); 113 | 114 | public static final String CONTENT_TYPE_REGEX = "([ |\t]*content-type[ |\t]*:)(.*)"; 115 | 116 | public static final Pattern CONTENT_TYPE_PATTERN = Pattern.compile(CONTENT_TYPE_REGEX, Pattern.CASE_INSENSITIVE); 117 | 118 | public static final String CONTENT_DISPOSITION_ATTRIBUTE_REGEX = "[ |\t]*([a-zA-Z]*)[ |\t]*=[ |\t]*['|\"]([^\"^']*)['|\"]"; 119 | 120 | public static final Pattern CONTENT_DISPOSITION_ATTRIBUTE_PATTERN = Pattern.compile(CONTENT_DISPOSITION_ATTRIBUTE_REGEX); 121 | 122 | public static final String CONTENT_LENGTH_REGEX = "Content-Length:"; 123 | public static final Pattern CONTENT_LENGTH_PATTERN = Pattern.compile(CONTENT_LENGTH_REGEX, Pattern.CASE_INSENSITIVE); 124 | 125 | public static final String USER_AGENT = "User-Agent:"; 126 | public static final Pattern USER_AGENT_PATTERN = Pattern.compile(USER_AGENT, Pattern.CASE_INSENSITIVE); 127 | 128 | public static final String HOST_REGEX = "Host:"; 129 | public static final Pattern CLIENT_HOST_PATTERN = Pattern.compile(HOST_REGEX, Pattern.CASE_INSENSITIVE); 130 | 131 | public static final String CONNECTION_TYPE_REGEX = "Connection:"; 132 | public static final Pattern CONNECTION_TYPE_PATTERN = Pattern.compile(CONNECTION_TYPE_REGEX, Pattern.CASE_INSENSITIVE); 133 | 134 | public static final String ACCEPT_ENCODING_REGEX = "Accept-Encoding:"; 135 | public static final Pattern ACCEPT_ENCODING_PATTERN = Pattern.compile(ACCEPT_ENCODING_REGEX, Pattern.CASE_INSENSITIVE); 136 | 137 | private static final String CONTENT_REGEX = "[ |\t]*([^/^ ^;^,]+/[^ ^;^,]+)"; 138 | 139 | private static final Pattern MIME_PATTERN = Pattern.compile(CONTENT_REGEX, Pattern.CASE_INSENSITIVE); 140 | 141 | private static final String CHARSET_REGEX = "[ |\t]*(charset)[ |\t]*=[ |\t]*['|\"]?([^\"^'^;^,]*)['|\"]?"; 142 | 143 | private static final Pattern CHARSET_PATTERN = Pattern.compile(CHARSET_REGEX, Pattern.CASE_INSENSITIVE); 144 | 145 | private static final String BOUNDARY_REGEX = "[ |\t]*(boundary)[ |\t]*=[ |\t]*['|\"]?([^\"^'^;^,]*)['|\"]?"; 146 | 147 | private static final Pattern BOUNDARY_PATTERN = Pattern.compile(BOUNDARY_REGEX, Pattern.CASE_INSENSITIVE); 148 | 149 | 150 | public static String WEB_DIR_PATH="/"; 151 | public static String SERVER_IP="localhost"; 152 | public static int SERVER_PORT=9000; 153 | public static boolean isStart=true; 154 | public static String INDEX_FILE_NAME="index.html"; 155 | 156 | 157 | public TinyWebServer(final String ip, final int port) throws IOException { 158 | 159 | InetAddress addr = InetAddress.getByName(ip); ////"172.31.0.186"); 160 | serverSocket = new ServerSocket(port, 100, addr); 161 | serverSocket.setSoTimeout(5000); //set timeout for listner 162 | 163 | } 164 | 165 | @Override 166 | public void run() { 167 | 168 | while (isStart) { 169 | try { 170 | //wait for new connection on port 5000 171 | Socket newSocket = serverSocket.accept(); 172 | Thread newClient = new EchoThread(newSocket); 173 | newClient.start(); 174 | } catch (SocketTimeoutException s) { 175 | } catch (IOException e) { 176 | } 177 | 178 | }//endof Never Ending while loop 179 | 180 | } 181 | 182 | public class EchoThread extends Thread { 183 | 184 | protected Socket socket; 185 | protected boolean nb_open; 186 | 187 | public EchoThread(Socket clientSocket) { 188 | this.socket = clientSocket; 189 | this.nb_open = true; 190 | } 191 | 192 | @Override 193 | public void run() { 194 | 195 | try { 196 | DataInputStream in = null; 197 | DataOutputStream out = null; 198 | 199 | if (socket.isConnected()) { 200 | in = new DataInputStream(socket.getInputStream()); 201 | out = new DataOutputStream(socket.getOutputStream()); 202 | } 203 | 204 | byte[] data = new byte[1500]; 205 | //socket.setSoTimeout(60 * 1000 * 5); 206 | 207 | while (in.read(data) != -1) { 208 | String recData = new String(data).trim(); 209 | //System.out.println("received data: \n" + recData); 210 | //System.out.println("------------------------------"); 211 | String[] header = recData.split("\\r?\\n"); 212 | 213 | String contentLen = "0"; 214 | String contentType = "text/html"; 215 | String connectionType = "keep-alive"; 216 | String hostname = ""; 217 | String userAgent = ""; 218 | String encoding = ""; 219 | 220 | String[] h1 = header[0].split(" "); 221 | if (h1.length == 3) { 222 | setRequestType(h1[0]); 223 | setHttpVer(h1[2]); 224 | } 225 | 226 | for (int h = 0; h < header.length; h++) { 227 | String value = header[h].trim(); 228 | 229 | //System.out.println(header[h]+" -> "+CONTENT_LENGTH_PATTERN.matcher(header[h]).find()); 230 | if (CONTENT_LENGTH_PATTERN.matcher(value).find()) { 231 | contentLen = value.split(":")[1].trim(); 232 | } else if (CONTENT_TYPE_PATTERN.matcher(value).find()) { 233 | contentType = value.split(":")[1].trim(); 234 | } else if (CONNECTION_TYPE_PATTERN.matcher(value).find()) { 235 | connectionType = value.split(":")[1].trim(); 236 | } else if (CLIENT_HOST_PATTERN.matcher(value).find()) { 237 | hostname = value.split(":")[1].trim(); 238 | } else if (USER_AGENT_PATTERN.matcher(value).find()) { 239 | for (String ua : value.split(":")) { 240 | if (!ua.equalsIgnoreCase("User-Agent:")) { 241 | userAgent += ua.trim(); 242 | } 243 | } 244 | } else if (ACCEPT_ENCODING_PATTERN.matcher(value).find()) { 245 | encoding = value.split(":")[1].trim(); 246 | } 247 | 248 | } 249 | 250 | if (!REQUEST_TYPE.equals("")) { 251 | String postData = ""; 252 | if (REQUEST_TYPE.equalsIgnoreCase("POST") && !contentLen.equals("0")) { 253 | postData = header[header.length - 1]; 254 | if (postData.length() > 0 && contentLen.length() > 0) { 255 | int len = Integer.valueOf(contentLen); 256 | postData = postData.substring(0, len); 257 | // System.out.println("Post data -> " + contentLen + " ->" + postData); 258 | } 259 | } 260 | 261 | // System.out.println("contentLen ->" + contentLen + "\ncontentType ->" + contentType + "\nhostname ->" + hostname + "\nconnectionType-> " + connectionType + "\nhostname ->" + hostname + "\nuserAgent -> " + userAgent); 262 | final String requestLocation = h1[1]; 263 | if (requestLocation != null) { 264 | processLocation(out, requestLocation, postData); 265 | } 266 | //System.out.println("requestLocation "+requestLocation); 267 | } 268 | 269 | } 270 | } catch (Exception er) { 271 | er.printStackTrace(); 272 | } 273 | 274 | } 275 | 276 | } 277 | 278 | public void processLocation(DataOutputStream out, String location, String postData) { 279 | 280 | String data = ""; 281 | switch (location) { 282 | case "/": 283 | //root location, server index file 284 | CONTENT_TYPE = "text/html"; 285 | data=readFile(WEB_DIR_PATH+"/"+INDEX_FILE_NAME); 286 | constructHeader(out, data.length() + "", data); 287 | break; 288 | default: 289 | 290 | System.out.println("url location -> " + location); 291 | URL geturl = getDecodedUrl("http://localhost" + location); 292 | String[] dirPath = geturl.getPath().split("/"); 293 | String fullFilePath=geturl.getPath(); 294 | if (dirPath.length > 1) { 295 | String fileName = dirPath[dirPath.length - 1]; 296 | HashMap qparms = (HashMap) splitQuery(geturl.getQuery()); 297 | if(REQUEST_TYPE.equals("POST")){ 298 | if (qparms==null){ qparms=new HashMap();} 299 | qparms.put("_POST", postData); 300 | } 301 | //System.out.println("File name " + fileName); 302 | //System.out.println("url parms " + qparms); 303 | CONTENT_TYPE = getContentType(fileName); 304 | if(!CONTENT_TYPE.equals("text/plain")){ 305 | // System.out.println("Full file path - >"+fullFilePath +" "+CONTENT_TYPE); 306 | 307 | if(CONTENT_TYPE.equals("image/jpeg") || CONTENT_TYPE.equals("image/png") || CONTENT_TYPE.equals("video/mp4")){ 308 | byte[] bytdata=readImageFiles(WEB_DIR_PATH+fullFilePath,CONTENT_TYPE); 309 | //System.out.println(bytdata.length); 310 | if(bytdata!=null){ 311 | constructHeaderImage(out, bytdata.length+"", bytdata); 312 | }else{ 313 | pageNotFound(); 314 | } 315 | }else{ 316 | data=readFile(WEB_DIR_PATH+fullFilePath); 317 | if(!data.equals("")){ 318 | constructHeader(out, data.length() + "", data); 319 | }else{ 320 | pageNotFound(); 321 | } 322 | } 323 | }else{ 324 | data = getResultByName(fileName, qparms); 325 | constructHeader(out, data.length() + "", data); 326 | } 327 | 328 | 329 | } 330 | 331 | } 332 | 333 | } 334 | 335 | public URL getDecodedUrl(String parms) { 336 | try { 337 | //String decodedurl =URLDecoder.decode(parms,"UTF-8"); 338 | URL aURL = new URL(parms); 339 | return aURL; 340 | } catch (Exception er) { 341 | } 342 | return null; 343 | } 344 | 345 | public static HashMap splitQuery(String parms) { 346 | try { 347 | final HashMap query_pairs = new HashMap<>(); 348 | final String[] pairs = parms.split("&"); 349 | for (String pair : pairs) { 350 | final int idx = pair.indexOf("="); 351 | final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair; 352 | if (!query_pairs.containsKey(key)) { 353 | query_pairs.put(key, ""); 354 | } 355 | final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; 356 | query_pairs.put(key, value); 357 | } 358 | return query_pairs; 359 | } catch (Exception er) { 360 | } 361 | return null; 362 | } 363 | 364 | public String getResultByName(String name, HashMap qparms) { 365 | try { 366 | String ClassName = "appapis.queryfiles.AppApis"; 367 | Class rClass = Class.forName(ClassName); // convert string classname to class 368 | Object obj = rClass.newInstance(); // invoke empty constructor 369 | Method getNameMethod = obj.getClass().getMethod(name, HashMap.class); 370 | STATUS = TinyWebServer.OKAY; 371 | return getNameMethod.invoke(obj, qparms).toString(); 372 | } catch (Exception er) { 373 | // er.printStackTrace(); 374 | return pageNotFound(); 375 | } 376 | } 377 | 378 | public void setRequestType(String type) { 379 | // System.out.println("REQUEST TYPE " + type); 380 | this.REQUEST_TYPE = type; 381 | } 382 | 383 | public void setHttpVer(String httpver) { 384 | // System.out.println("REQUEST ver " + httpver); 385 | this.HTTP_VER = httpver; 386 | } 387 | 388 | public String getRequestType() { 389 | return this.REQUEST_TYPE; 390 | } 391 | 392 | public String getHttpVer() { 393 | return this.HTTP_VER; 394 | } 395 | 396 | public String pageNotFound() { 397 | STATUS = NOT_FOUND; 398 | CONTENT_TYPE = "text/html"; 399 | //customize your page here 400 | return "" 401 | + "Page not found | Firefly web server" 402 | + "

Requested page not found

"; 403 | } 404 | 405 | //hashtable initilization for content types 406 | static Hashtable mContentTypes = new Hashtable(); 407 | 408 | { 409 | mContentTypes.put("js", "application/javascript"); 410 | mContentTypes.put("php", "text/html"); 411 | mContentTypes.put("java", "text/html"); 412 | mContentTypes.put("json", "application/json"); 413 | mContentTypes.put("png", "image/png"); 414 | mContentTypes.put("jpg", "image/jpeg"); 415 | mContentTypes.put("html", "text/html"); 416 | mContentTypes.put("css", "text/css"); 417 | mContentTypes.put("mp4", "video/mp4"); 418 | mContentTypes.put("mov", "video/quicktime"); 419 | mContentTypes.put("wmv", "video/x-ms-wmv"); 420 | 421 | } 422 | 423 | //get request content type 424 | public static String getContentType(String path) { 425 | String type = tryGetContentType(path); 426 | if (type != null) { 427 | return type; 428 | } 429 | return "text/plain"; 430 | } 431 | 432 | //get request content type from path 433 | public static String tryGetContentType(String path) { 434 | int index = path.lastIndexOf("."); 435 | if (index != -1) { 436 | String e = path.substring(index + 1); 437 | String ct = mContentTypes.get(e); 438 | // System.out.println("content type: " + ct); 439 | if (ct != null) { 440 | return ct; 441 | } 442 | } 443 | return null; 444 | } 445 | 446 | private void constructHeader(DataOutputStream output, String size, String data) { 447 | SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US); 448 | gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT")); 449 | PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output)), false); 450 | pw.append("HTTP/1.1 ").append(STATUS).append(" \r\n"); 451 | if (this.CONTENT_TYPE != null) { 452 | printHeader(pw, "Content-Type", this.CONTENT_TYPE); 453 | } 454 | printHeader(pw, "Date", gmtFrmt.format(new Date())); 455 | printHeader(pw, "Connection", (this.keepAlive ? "keep-alive" : "close")); 456 | printHeader(pw, "Content-Length", size); 457 | printHeader(pw, "Server", SERVER_NAME); 458 | pw.append("\r\n"); 459 | pw.append(data); 460 | pw.flush(); 461 | //pw.close(); 462 | } 463 | 464 | private void constructHeaderImage(DataOutputStream output, String size, byte[] data) { 465 | try{ 466 | 467 | SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US); 468 | gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT")); 469 | PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output)), false); 470 | pw.append("HTTP/1.1 ").append(STATUS).append(" \r\n"); 471 | if (this.CONTENT_TYPE != null) { 472 | printHeader(pw, "Content-Type", this.CONTENT_TYPE); 473 | } 474 | printHeader(pw, "Date", gmtFrmt.format(new Date())); 475 | printHeader(pw, "Connection", (this.keepAlive ? "keep-alive" : "close")); 476 | printHeader(pw, "Content-Length", size); 477 | printHeader(pw, "Server", SERVER_NAME); 478 | pw.append("\r\n"); 479 | pw.flush(); 480 | output.write(data); 481 | output.flush(); 482 | //System.out.println("data sent success"); 483 | 484 | //pw.close(); 485 | }catch(Exception er){er.printStackTrace();} 486 | 487 | } 488 | 489 | 490 | @SuppressWarnings("static-method") 491 | protected void printHeader(PrintWriter pw, String key, String value) { 492 | pw.append(key).append(": ").append(value).append("\r\n"); 493 | } 494 | 495 | public byte[] readImageFiles(String fileName,String filetype){ 496 | try{ 497 | File ifile=new File(fileName); 498 | if(ifile.exists()){ 499 | if(filetype.equalsIgnoreCase("image/png") || filetype.equalsIgnoreCase("image/jpeg") || filetype.equalsIgnoreCase("image/gif") || filetype.equalsIgnoreCase("image/jpg")){ 500 | FileInputStream fis = new FileInputStream(fileName); 501 | byte[] buffer = new byte[fis.available()]; 502 | while (fis.read(buffer) != -1) {} 503 | fis.close(); 504 | return buffer; 505 | } 506 | }else{ 507 | 508 | } 509 | }catch(Exception er){} 510 | return null; 511 | } 512 | public String readFile(String fileName){ 513 | String content=""; 514 | try{ 515 | File ifile=new File(fileName); 516 | if(ifile.exists()){ 517 | FileInputStream fis = new FileInputStream(fileName); 518 | byte[] buffer = new byte[10]; 519 | StringBuilder sb = new StringBuilder(); 520 | while (fis.read(buffer) != -1) { 521 | sb.append(new String(buffer)); 522 | buffer = new byte[10]; 523 | } 524 | fis.close(); 525 | content = sb.toString(); 526 | }else{ 527 | pageNotFound(); 528 | return content; 529 | } 530 | }catch(Exception er){ 531 | pageNotFound(); 532 | return ""; 533 | } 534 | return content; 535 | } 536 | 537 | 538 | public static void init(String ip,int port,String public_dir){ 539 | 540 | SERVER_IP=ip; 541 | SERVER_PORT=port; 542 | WEB_DIR_PATH=public_dir; 543 | scanFileDirectory(); 544 | 545 | } 546 | 547 | public static void startServer(String ip,int port,String public_dir){ 548 | try { 549 | 550 | isStart=true; 551 | init(ip,port,public_dir); 552 | Thread t = new TinyWebServer(SERVER_IP, SERVER_PORT); 553 | t.start(); 554 | System.out.println("Server Started !"); 555 | 556 | } catch (IOException e) { 557 | e.printStackTrace(); 558 | } catch (Exception e) { 559 | } 560 | } 561 | 562 | public static void stopServer(){ 563 | if(isStart){ 564 | try{ 565 | isStart=false; 566 | serverSocket.close(); 567 | System.out.println("Server stopped running !"); 568 | }catch(IOException er){ 569 | er.printStackTrace(); 570 | } 571 | } 572 | } 573 | 574 | 575 | //scan for index file 576 | public static void scanFileDirectory(){ 577 | boolean isIndexFound=false; 578 | try{ 579 | File file=new File(WEB_DIR_PATH); 580 | if(file.isDirectory()){ 581 | File[] allFiles=file.listFiles(); 582 | for (File allFile : allFiles) { 583 | //System.out.println(allFile.getName().split("\\.")[0]); 584 | if(allFile.getName().split("\\.")[0].equalsIgnoreCase("index")){ 585 | TinyWebServer.INDEX_FILE_NAME=allFile.getName(); 586 | isIndexFound=true; 587 | } 588 | } 589 | } 590 | 591 | }catch(Exception er){} 592 | 593 | if(!isIndexFound){ 594 | System.out.println("Index file not found !"); 595 | } 596 | } 597 | 598 | /* //use for testing 599 | public static void main(String[] args) { 600 | try { 601 | 602 | Thread t = new TinyWebServer(SERVER_IP, SERVER_PORT); 603 | t.start(); 604 | System.out.println("Server Started !"); 605 | 606 | } catch (IOException e) { 607 | e.printStackTrace(); 608 | } catch (Exception e) { 609 | } 610 | }*/ 611 | 612 | } 613 | -------------------------------------------------------------------------------- /AndroidWebServer/src/appapis/queryfiles/AppApis.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License 3 | * 4 | * Copyright 2018 Sonu Auti http://sonuauti.com twitter @SonuAuti 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | package appapis.queryfiles; 25 | 26 | import java.util.HashMap; 27 | 28 | /** 29 | * 30 | * @author cis 31 | */ 32 | public class AppApis { 33 | 34 | public AppApis(){ 35 | } 36 | 37 | public String helloworld(HashMap qparms){ 38 | //demo of simple html webpage from controller method 39 | androidhttpweb.TinyWebServer.CONTENT_TYPE="text/html"; 40 | return "Simple HTML and Javascript Demo\n" + 41 | " \n" + 44 | " \n" + 45 | " \n" + 46 | "

Say Hello !

\n" + 47 | "
\n" + 48 | "
\n" + 49 | "
\n" + 50 | "
\n" + 51 | "
\n" + 52 | "
\n" + 53 | " "; 54 | } 55 | 56 | public String simplejson(HashMap qparms){ 57 | //simple json output demo from controller method 58 | String json = "{\"name\":\"sonu\",\"age\":29}"; 59 | return json.toString(); 60 | } 61 | 62 | public String simplegetparm(HashMap qparms){ 63 | /* 64 | qparms is hashmap of get and post parameter 65 | 66 | simply use qparms.get(key) to get parameter value 67 | user _POST as key for post data 68 | e.g to get post data use qparms.get("_POST"), return will be post method 69 | data 70 | */ 71 | 72 | System.out.println("output in simplehelloworld "+qparms); 73 | String p=""; 74 | if(qparms!=null){ 75 | p=qparms.get("age")+""; 76 | } 77 | String json = "{\"name\":\"sonu\",\"age\":"+p+",\"isp\":yes}"; 78 | return json.toString(); 79 | } 80 | 81 | 82 | //implement web callback here and access them using method name 83 | } 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sonu Auti 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Web Server (FireFly) 2 | Simple and Small footprint TCP/IP Web Server for Android in Java 3 | 4 | This is standalone, multithreaded, almost or No dependancy ! http server in Java with example use in Android. 5 | 6 | Features supported 7 | - Support basic GET, POST requests 8 | - Render html files 9 | - Render jpeg,png,gif 10 | - Custom api for dynamic web pages (mvc) 11 | - Support javascript rendring 12 | - Multithreaded, support mulitple client 13 | 14 | What it does not do? 15 | - File upload, video rendering 16 | 17 | 18 | # Getting Started 19 | ## How to use it in Android? 20 | 1. Add the follow permission to your manifest file 21 | ```java 22 | 23 | ``` 24 | 2. Copy TinyWebServer.java class from src dir to your android project package 25 | 3. Call following from android service or process 26 | 27 | 28 | ```java 29 | @Override 30 | protected void onCreate(Bundle savd){ 31 | super.onCreate(savd); 32 | ... 33 | //call contructor with local ip, port , public html directory path 34 | TinyWebServer.startServer("localhost",9000, "/web/public_html"); 35 | } 36 | 37 | @Override 38 | public void onDestroy(){ 39 | super.onDestroy(); 40 | //stop webserver on destroy of service or process 41 | TinyWebServer.stopServer(); 42 | } 43 | ``` 44 | 45 | ## How to write custom api? 46 | 47 | 48 | 1. Copy AppApis.java from src directory 49 | 2. keep the package name same for AppApis.java like "appapis.queryfiles" 50 | 3. open AppApis.java and write your own mehtod/function inside AppApis.java 51 | for example, 52 | 53 | ```java 54 | public String myfirstapi(HashMap qparms){ 55 | //todo - write your api logic here 56 | //qparms is collection of GET and POST parameters 57 | } 58 | ``` 59 | 60 | you can access this api -> http://localhost:9000/myfirstapi 61 | 62 | 63 | 64 | ## How to check demo? 65 | - Run the code and hit browser with http://localhost:9000/helloworld 66 | - here port number is 9000 67 | - localhost or your device ip address 68 | - helloworld is api method inside AppApis.java 69 | 70 | ![Demo ScreenShot](https://github.com/sonuauti/Android-Web-Server/blob/master/demo.png) 71 | 72 | 73 | Design, Build, Tested by 74 | twitter , github /@sonuauti 75 | 76 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonuauti/Android-Web-Server/313f3decf6dee47549046dfb220456aab8f7ca12/demo.png --------------------------------------------------------------------------------