📄 negotiatedframe.java
字号:
*/ public boolean getPutPolicy() { Boolean val = (Boolean) getValue(ATTR_PUT_POLICY, null); if (val == null) // strict by default return true; return val.booleanValue(); } public void setPutPolicy(Boolean strict) { setValue(ATTR_PUT_POLICY, strict); } public void setPutPolicy(boolean strict) { setValue(ATTR_PUT_POLICY, new Boolean(strict)); } /** * get the variant checking policy */ public boolean getParanoidVariantCheck() { Boolean val = (Boolean) getValue(ATTR_PUT_POLICY, null); if (val == null) // strict by default return false; // not paranoid -- only check when editing variants return val.booleanValue(); } /** * Get the variant resources. * This is somehow broken, it shouldn't allocate the array of variants * on each call. However, don't forget that the list of variants can be * dynamically edited, this means that if we are to keep a cache of it * (as would be the case if we kept the array of variants as instance var) * we should also take care of editing of attributes (possible, but I * just don't have enough lifes). * @return An array of ResourceReference, or <strong>null</strong>. * @exception ProtocolException If one of the variants doesn't exist. */ public ResourceReference[] getVariantResources() throws ProtocolException { // Get the variant names: String names[] = getVariantNames() ; if ( names == null ) return null ; int oldlength = names.length ; if (getParanoidVariantCheck()) { names = checkVariants(names) ; } // Look them up in our parent directory: ResourceReference variants[] = new ResourceReference[names.length] ; ResourceReference r_parent = resource.getParent() ; try { DirectoryResource parent= (DirectoryResource)r_parent.unsafeLock(); int missing = 0; for (int i = 0 ; i < names.length ; i++) { variants[i] = parent.lookup(names[i]) ; if (variants[i] == null) missing++; } if (missing > 0) { int kept = names.length - missing; if (kept < 1) return null; String newNames[] = new String[kept]; int j = 0; int i = 0; while (i < variants.length) { if (variants[i] != null) { newNames[j++] = names[i++]; } else { i++; } } setVariants(newNames); //recompute Variant Resources return getVariantResources(); } else if (oldlength > names.length){ setVariants(names); } } catch (InvalidResourceException ex) { throw new HTTPException("invalid parent for negotiation"); } finally { r_parent.unlock(); } return variants ; } /** * Print the current negotiation state. * @param header The header to print first. * @param states The current negotiation states. */ protected void printNegotiationState (String header, Vector states) { if ( debug ) { System.out.println ("------" + header) ; for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; System.out.println (state) ; } System.out.println ("-----") ; } } /** * Negotiate among content encodings. * <p>BUG: This will work only for single encoded variants. * @param states The current negotiation states. * @param request The request to handle. * @return a boolean. * @exception ProtocolException If one of the variants doesn't exist. */ protected boolean negotiateContentEncoding (Vector states, Request request) throws ProtocolException { if ( ! request.hasAcceptEncoding() ) { // All encodings accepted: for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; state.setContentEncodingQuality(1.0) ; } } else { HttpAcceptEncoding encodings[] = request.getAcceptEncoding() ; for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; ResourceReference rr = state.getResource(); try { FramedResource resource = (FramedResource)rr.unsafeLock() ; HTTPFrame itsframe = (HTTPFrame) resource.getFrame(httpFrameClass); if (itsframe != null) { String ve; if ( !itsframe.definesAttribute("content-encoding") ) { ve = "identity"; // default encoding state.setContentEncodingQuality (1.0) ; } else { ve = itsframe.getContentEncoding() ; state.setContentEncodingQuality (0.01) ; } int jidx = -1 ; for (int j = 0 ; j < encodings.length ; j++) { if (encodings[j].getEncoding().equals(ve)) { jidx = j; break; } if (encodings[j].getEncoding().equals("*")) jidx = j; // default '*' if no better match } if ( jidx >= 0 ) state.setContentEncodingQuality (encodings[jidx].getQuality() - jidx * 0.001) ; } } catch (InvalidResourceException ex) { } finally { rr.unlock(); } } // FIXME We should check here against unlegible variants as now } return false ; } /** * Negotiate on charsets. * The algorithm is described in RFC2616 (Obsoletes RFC2068) * @param states The current states of negotiation. * @param request The request to handle. */ protected boolean negotiateCharsetQuality (Vector states , Request request) { if ( ! request.hasAcceptCharset() ) { // All variants get a quality of 1.0 for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; state.setCharsetQuality (1.0) ; } } else { // The browser has given some preferences: HttpAcceptCharset charsets[] = request.getAcceptCharset() ; for (int i = 0 ; i < states.size() ; i++ ) { VariantState state = (VariantState) states.elementAt(i) ; // Get the most specific match for this variant: ResourceReference rr = state.getResource(); try { FramedResource resource = (FramedResource)rr.unsafeLock() ; HTTPFrame itsframe = (HTTPFrame) resource.getFrame(httpFrameClass); if (itsframe != null) { MimeType vt = itsframe.getContentType(); String fcharset = vt.getParameterValue("charset"); // if not defined in the frame, it must be the default if (fcharset == null) { fcharset = "ISO-8859-1"; } double qual = 0.0 ; boolean default_done = false; String charset; for (int j = 0 ; j < charsets.length ; j++) { charset = charsets[j].getCharset(); if (charset.equals("*")) { default_done = true; if (qual == 0) { qual = charsets[j].getQuality()-0.001*j; } } else { if ( charset.equals("ISO-8859-1")) default_done = true; if ( charset.equals(fcharset)) if (charsets[j].getQuality() > qual) { qual =charsets[j].getQuality()-0.001*j; } } } if (!default_done && fcharset.equals("ISO-8859-1")) qual = 1.0 - 0.001*charsets.length; state.setCharsetQuality(qual) ; } } catch (InvalidResourceException ex) { //FIXME } finally { rr.unlock(); } } } return false ; } /** * Negotiate among language qualities. * <p>BUG: This will only work for variants that have one language tag. * @param states The current states of negotiation. * @param request The request to handle. * @return a boolean. * @exception ProtocolException If one of the variants doesn't exist. */ protected boolean negotiateLanguageQuality (Vector states , Request request) throws ProtocolException { if ( ! request.hasAcceptLanguage() ) { for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; state.setLanguageQuality (1.0) ; } } else { HttpAcceptLanguage languages[] = request.getAcceptLanguage() ; LanguageTag req_lang[] = new LanguageTag[languages.length]; for (int i = 0 ; i < languages.length ; i++) { req_lang[i] = new LanguageTag(languages[i].getLanguage()); } boolean varyLang = false ; for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; ResourceReference rr = state.getResource(); try { FramedResource resource = (FramedResource)rr.unsafeLock() ; HTTPFrame itsframe = (HTTPFrame) resource.getFrame(httpFrameClass); if (itsframe != null) { if ( !itsframe.definesAttribute("content-language") ) { state.setLanguageQuality (-1.0) ; } else { varyLang = true ; String lang = itsframe.getContentLanguage() ; LanguageTag ftag = new LanguageTag(lang); int jmatch = -1 ; int jidx = -1 ; for (int j = 0 ; j < languages.length ; j++) { int match = ftag.match(req_lang[j]); if ( match > jmatch ) { jmatch = match ; jidx = j ; } } if ( jidx < 0 ) state.setLanguageQuality(0.01) ; else { // little hack for first state.setLanguageQuality ( languages[jidx].getQuality()-jidx*0.001) ; } } } } catch (InvalidResourceException ex) { //FIXME } finally { rr.unlock(); } } if ( varyLang ) { for (int i = 0 ; i < states.size() ; i++) { VariantState s = (VariantState) states.elementAt(i); if ( s.getLanguageQuality() < 0 ) s.setLanguageQuality (0.5) ; } } else { for (int i = 0 ; i < states.size() ; i++) { VariantState s = (VariantState) states.elementAt(i) ; s.setLanguageQuality (1.0) ; } } } return false ; } /** * Negotiate among content types. * @param states The current states of negotiation. * @param request The request to handle. * @return a boolean. * @exception ProtocolException If one of the variants doesn't exist. */ protected boolean negotiateContentType (Vector states, Request request) throws ProtocolException { if ( ! request.hasAccept() ) { // All variants get a quality of 1.0 for (int i = 0 ; i < states.size() ; i++) { VariantState state = (VariantState) states.elementAt(i) ; state.setQuality (1.0) ; } } else { // The browser has given some preferences: HttpAccept accepts[] = request.getAccept() ; for (int i = 0 ; i < states.size() ; i++ ) { VariantState state = (VariantState) states.elementAt(i) ; // Get the most specific match for this variant: ResourceReference rr = state.getResource(); try { FramedResource resource = (FramedResource)rr.unsafeLock() ; HTTPFrame itsframe = (HTTPFrame) resource.getFrame(httpFrameClass); if (itsframe != null) { MimeType vt = itsframe.getContentType(); int jmatch = -1 ; int jidx = -1 ; for (int j = 0 ; j < accepts.length ; j++) { try { int match = vt.match(accepts[j].getMimeType()); if ( match > jmatch ) { jmatch = match ; jidx = j ; } } catch (HttpInvalidValueException ivex) { // There is a bad acept header here // let's be cool and ignore it // FIXME we should answer with a Bad Request } } if ( jidx < 0 ) state.setQuality (0.0) ; else state.setQuality(accepts[jidx].getQuality() -jidx*0.001) ; } } catch (InvalidResourceException ex) { //FIXME } finally { rr.unlock(); } } } return false ; } /** * Negotiate among the various variants for the Resource. * We made our best efforts to be as compliant as possible to the HTTP/1.0 * content negotiation algorithm. * @param request the incomming request. * @return a RefourceReference instance. * @exception ProtocolException If one of the variants doesn't exist. */ protected ResourceReference negotiate (Request request) throws ProtocolException { // Check for zero or one variant: ResourceReference variants[] = getVariantResources() ; if (variants == null) { try { getResource().delete(); } catch (MultipleLockException ex) { //will be deleted later... } finally { Reply reply = request.makeReply(HTTP.NOT_FOUND); reply.setContent ("<h1>Document not found</h1>"+ "<p>The document "+request.getURL()+ " has no acceptable variants "+ "(probably deleted)."); throw new HTTPException (reply); } } if ( variants.length < 2 ) { if ( variants.length == 0 ) { try { getResource().delete(); } catch (MultipleLockException ex) { //will be deleted later... } finally { Reply reply = request.makeReply(HTTP.NOT_FOUND); reply.setContent ("<h1>Document not found</h1>"+ "<p>The document "+request.getURL()+ " has no acceptable variants "+ "(probably deleted)."); throw new HTTPException (reply); } } else { return variants[0] ; } } // Build a vector of variant negociation states, one per variants: Vector states = new Vector (variants.length) ; for (int i = 0 ; i < variants.length ; i++) { double qs = 1.0 ; try { FramedResource resource = (FramedResource) variants[i].unsafeLock() ; HTTPFrame itsframe = (HTTPFrame) resource.getFrame(httpFrameClass); if (itsframe != null) { if ( itsframe.definesAttribute ("quality") ) qs = itsframe.getQuality() ; if ( qs > REQUIRED_QUALITY ) states.addElement(new VariantState (variants[i], qs)) ; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -