1 14 15 package mx4j.tools.adaptor.http; 16 17 18 import java.io.BufferedInputStream ; 19 import java.io.IOException ; 20 import java.io.InputStream ; 21 import java.net.URLDecoder ; 22 import java.util.HashMap ; 23 import java.util.Map ; 24 import java.util.NoSuchElementException ; 25 import java.util.StringTokenizer ; 26 27 28 33 34 public class HttpInputStream extends BufferedInputStream 35 36 { 37 38 39 42 43 private String method; 44 45 46 49 50 private String path; 51 52 53 56 57 private String queryString; 58 59 60 63 64 private float version; 65 66 67 70 71 private Map headers = new HashMap (); 72 73 74 private Map variables = new HashMap (); 75 76 77 82 83 public HttpInputStream(InputStream in) 84 85 { 86 87 super(in); 88 89 } 90 91 92 97 98 public String getMethod() 99 100 { 101 102 return method; 103 104 } 105 106 107 112 113 public String getPath() 114 115 { 116 117 return path; 118 119 } 120 121 122 127 128 public String getQueryString() 129 130 { 131 132 return queryString; 133 134 } 135 136 137 142 143 public float getVersion() 144 145 { 146 147 return version; 148 149 } 150 151 152 158 159 public String getHeader(String name) 160 161 { 162 163 return (String )headers.get(name); 164 165 } 166 167 168 174 175 public Map getHeaders() 176 177 { 178 179 return headers; 180 181 } 182 183 184 189 190 public void readRequest() throws IOException 191 192 { 193 194 String request = readLine(); 195 196 if (request == null) 197 198 { 199 200 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Null query"); 201 202 } 203 204 206 StringTokenizer parts = new StringTokenizer (request); 207 208 try 209 210 { 211 212 parseMethod(parts.nextToken()); 213 214 parseRequest(parts.nextToken()); 215 216 } 217 218 catch (NoSuchElementException ex) 219 220 { 221 222 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, request); 223 224 } 225 226 if (parts.hasMoreTokens()) 227 228 { 229 230 parseVersion(parts.nextToken()); 231 232 } 233 234 else 235 236 { 237 238 version = 0.9f; 239 240 } 241 242 if (version >= 1.0f) 243 244 { 245 246 readHeaders(); 247 248 parseVariables(); 249 250 } 251 252 } 253 254 255 261 262 public String readLine() throws IOException 263 264 { 265 266 StringBuffer line = new StringBuffer (64); 267 268 line.delete(0, line.length()); 269 270 int c; 271 272 while (((c = read()) != -1) && (c != '\n') && (c != '\r')) 273 274 { 275 276 line.append((char)c); 277 278 } 279 280 if ((c == '\r') && ((c = read()) != '\n') && (c != -1)) 281 282 { 283 284 --pos; 285 286 } 287 288 if ((c == -1) && (line.length() == 0)) 289 290 { 291 292 return null; 293 294 } 295 296 else 297 298 { 299 300 return line.toString(); 301 302 } 303 304 } 305 306 307 316 317 public Map getVariables() 318 319 { 320 321 return variables; 322 323 } 324 325 326 333 334 public String getVariable(String name) 335 336 { 337 338 if (variables.containsKey(name)) 339 340 { 341 342 Object variable = variables.get(name); 343 344 if (variable instanceof String ) 345 346 { 347 348 return (String )variable; 349 350 } 351 352 else if (variable instanceof String []) 353 354 { 355 356 return ((String [])variable)[0]; 357 358 } 359 360 } 361 362 return null; 363 364 } 365 366 367 372 373 public String [] getVariableValues(String name) 374 375 { 376 377 if (variables.containsKey(name)) 378 379 { 380 381 Object variable = variables.get(name); 382 383 if (variable instanceof String []) 384 385 { 386 387 return (String [])variable; 388 389 } 390 else if (variable instanceof String ) 391 392 { 393 394 String [] result = new String [1]; 395 396 result[0] = (String )variable; 397 398 return result; 399 400 } 401 402 } 403 404 return null; 405 406 } 407 408 409 412 413 protected void parseVariables() throws HttpException 414 415 { 416 417 try 418 419 { 420 421 423 String variableHolder = ""; 424 425 if (method.equals(HttpConstants.METHOD_POST) && "application/x-www-form-urlencoded".equals(headers.get("content-type")) 426 427 && (headers.get("content-length") != null)) 428 429 { 430 431 if ("chunked".equals(headers.get("transfer-encoding"))) 432 433 { 434 435 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Sorry I don't understand chunked requests"); 436 437 } 438 439 StringBuffer buffer = new StringBuffer (); 440 441 int size = Integer.parseInt((String )headers.get("content-length")); 442 443 mark(size); 444 445 for (int i = 0; i < size; i++) 446 447 { 448 449 int j = read(); 450 451 if (j >= 0) 452 453 { 454 455 buffer.append((char)j); 456 457 } 458 459 else 460 461 { 462 463 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Request not understood"); 464 465 } 466 467 } 468 469 variableHolder = buffer.toString(); 470 471 reset(); 472 473 } 474 475 else if (method.equals(HttpConstants.METHOD_GET)) 476 477 { 478 479 variableHolder = getQueryString(); 480 481 } 482 483 else 484 485 { 486 487 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, "Request not understood"); 488 489 } 490 491 StringTokenizer parser = new StringTokenizer (variableHolder, "&"); 492 493 while (parser.hasMoreTokens()) 494 495 { 496 497 String command = parser.nextToken(); 498 499 int equalIndex = command.indexOf('='); 500 501 if (equalIndex > 0) 502 503 { 504 505 String variableName = URLDecoder.decode(command.substring(0, equalIndex)); 506 507 String variableValue = URLDecoder.decode(command.substring(equalIndex + 1, command.length())); 508 509 variableValue = new String (variableValue.getBytes(), "UTF-8"); 510 511 if (variables.get(variableName) != null) 512 { 513 514 Object value = variables.get(variableName); 515 516 String [] newValue = null; 517 518 if (value instanceof String ) 519 520 { 521 522 newValue = new String [2]; 523 524 newValue[0] = variableValue; 525 526 newValue[1] = (String )value; 527 528 } 529 530 else 531 532 { 533 534 String [] oldValue = (String [])value; 535 536 newValue = new String [oldValue.length + 1]; 537 538 System.arraycopy(oldValue, 0, newValue, 1, oldValue.length); 539 540 newValue[0] = variableValue; 541 542 } 543 544 variables.put(variableName, newValue); 545 546 } 547 548 else 549 550 { 551 552 variables.put(variableName, variableValue); 553 554 } 555 556 } 557 558 } 559 560 } 561 562 catch (Exception e) 563 564 { 565 566 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, getQueryString()); 567 568 } 569 570 } 571 572 573 579 580 protected void parseMethod(String method) throws HttpException 581 582 { 583 584 if (method.equals(HttpConstants.METHOD_GET)) 585 586 { 587 588 this.method = HttpConstants.METHOD_GET; 589 590 } 591 592 else if (method.equals(HttpConstants.METHOD_POST)) 593 594 { 595 596 this.method = HttpConstants.METHOD_POST; 597 598 } 599 600 else 601 602 { 603 604 throw new HttpException(HttpConstants.STATUS_NOT_IMPLEMENTED, method); 605 606 } 607 608 } 609 610 611 617 618 protected void parseRequest(String request) throws HttpException 619 620 { 621 622 if (!request.startsWith("/")) 623 624 { 625 626 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, request); 627 628 } 629 630 int queryIdx = request.indexOf('?'); 631 632 if (queryIdx == -1) 633 634 { 635 636 path = HttpUtil.canonicalizePath(request); 637 638 queryString = ""; 639 640 } 641 642 else 643 644 { 645 646 path = HttpUtil.canonicalizePath(request.substring(0, queryIdx)); 647 648 queryString = request.substring(queryIdx + 1); 649 650 } 651 652 } 653 654 655 661 662 protected void parseVersion(String verStr) throws HttpException 663 664 { 665 666 if (!verStr.startsWith("HTTP/")) 667 668 { 669 670 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, verStr); 671 672 } 673 674 try 675 676 { 677 678 version = Float.valueOf(verStr.substring(5)).floatValue(); 679 680 } 681 682 catch (NumberFormatException ex) 683 684 { 685 686 throw new HttpException(HttpConstants.STATUS_BAD_REQUEST, verStr); 687 688 } 689 690 } 691 692 693 698 699 protected void readHeaders() throws IOException 700 701 { 702 703 String header; 704 705 while (((header = readLine()) != null) && !header.equals("")) 706 707 { 708 709 int colonIdx = header.indexOf(':'); 710 711 if (colonIdx != -1) 712 713 { 714 715 String name = header.substring(0, colonIdx); 716 717 String value = header.substring(colonIdx + 1); 718 719 headers.put(name.toLowerCase(), value.trim()); 720 721 } 722 723 } 724 725 } 726 727 } 728 729 | Popular Tags |